java_多线程4种实现方式

2018-06-18 03:50:03来源:未知 阅读 ()

新老客户大回馈,云服务器低至5折

1.继承Thread

 

 class MyThread extends Thread{      
 private int ticket = 5 ;               
      public void run(){   
                  for(int i=0;i<100;i++){
                         if(this.ticket>0){
                                 System.out.println("卖票:ticket = " + ticket--) ;
                         }
                 }
         }
};
 public class ThreadDemo0{
         public static void main(String args[]){
              MyThread mt1 = new MyThread() ;       
              MyThread mt2 = new MyThread() ;   
              MyThread mt3 = new MyThread() ;  
               mt1.run() ;       //注意:调用的是run,并不是start           
mt2.run() ;
mt3.run() ;
} };

 

class Mythread extends Thread{      
             private int ticket = 5 ;               
              public void run(){   
                     for(int i=0;i<100;i++){
                            if(this.ticket>0){
                                      System.out.println("卖票:ticket = " + ticket--) ;
                              }
                    }
              }
     };
     public class ThreadDemo0{
             public static void main(String args[]){
                 Mythread mt1 = new Mythread() ;         
                 Mythread mt2 = new Mythread() ;         
                 Mythread mt3 = new Mythread() ;         
                    mt1.start();   
                    mt2.start();    
                    mt3.start();   
           }
    };

 

start()用来启动一个线程,当调用start()方法时,系统才会开启一个线程,通过Thead类中start()方法来启动的线程处于就绪状态(可运行状态),
此时并没有运行,一旦得到CPU时间片,就自动开始执行run()方法。此时不需要等待run()方法执行完也可以继续执行下面的代码,
run()方法是在本线程里的,只是线程里的一个函数,而不是多线程的。如果直接调用run(),其实就相当于是调用了一个普通函数而已,直接调用run()方法必须等待run()方法执行完毕才能执行下面的代码,所以执行路径还是只有一条,根本就没有线程的特征,所以在多线程执行时要使用start()方法而不是run()方法。
2.实现Runnable接口(无返回值得任务必须实现Runnable接口,可返回值的任务必须实现Callable接口

public class Runnable_xc {
    public static void main(String[] args) {
        M1 m1 = new M1();
        M2 m2 = new M2();
        Thread t1 = new Thread(m1);
        Thread t2 = new Thread(m2);
        t1.start();
        t2.start();
    }
}
class M1 implements Runnable {
    public void run() {
        int i = 100;
        while (i > 0) {
            System.out.println(i--);
        }
    }
}

class M2 implements Runnable {
    public void run() {
        int i = 100;
        while (i > 0) {
            System.out.println(i--);
        }
    }
}

以上两种方式在任务执行完成之后无法获取返回结果,如果就以上两种方法的话,推荐使用Runnable,简单的说就是因为单继承多实现

3.实现Callable接口通过FutureTask包装器来创建Thread线程(无返回值得任务必须实现Runnable接口,可返回值的任务必须实现Callable接口,重要的事情说2遍

Callable接口(也只有一个方法)定义如下:   泛型接口,call()函数返回的类型就是传递进来的V类型,Callable经常和java线程池一起启用:

 

public interface Callable<V>   { 
  V call() throws Exception;   } 

 

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class MyCallable implements Callable<String> {

    public String call() throws Exception {
        int i = 100;
        String rs = "false";
        while (i > 0) {
            System.out.println(i--);
            if (i == 50) {
                Thread.sleep(3000);
            }
            if (i == 1) {
                rs = "TRUE";
            }
        }
        return rs;
    }

    public static void main(String[] args) {
        Callable<String> oneCallable0 = new MyCallable(); // 由Callable<String>创建一个FutureTask<String>对象:
        Callable<String> oneCallable1 = new MyCallable();
        FutureTask<String> oneTask0 = new FutureTask<String>(oneCallable0);
        FutureTask<String> oneTask1 = new FutureTask<String>(oneCallable1);

        Thread oneThread0 = new Thread(oneTask0); // 由FutureTask<String>创建一个Thread对象:
        Thread oneThread1 = new Thread(oneTask1);

        oneThread0.start();
        oneThread1.start();

        try {
            System.out.println(oneTask0.get());
            System.out.println(oneTask1.get());//结果
        } catch (InterruptedException | ExecutionException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}

 

4.使用ExecutorServiceCallableFuture

ExecutorService是一个线程池接口,执行Callable任务后,可以获取一个Future对象,在该对象上调用get就可以获取到Callable任务返回的Object,再结合ExecutorService接口就可以实现有返回结果的多线程

 

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

public class TH_POOL {
	public static void main(String[] args) throws ExecutionException, InterruptedException {
		System.out.println("----程序开始运行----");
		Date date1 = new Date();
		int taskSize = 5; // 创建一个线程池
		ExecutorService pool = Executors.newFixedThreadPool(taskSize); // 创建多个有返回值的任务
		List<Future> list = new ArrayList<Future>();
		for (int i = 0; i < taskSize; i++) {
			Callable c = new MyCallable3(i + " "); // 执行任务并获取Future对象
			Future f = pool.submit(c);
			list.add(f);
		}
		// 关闭线程池
		pool.shutdown();

		// 获取所有并发任务的运行结果
		for (Future f : list) {
			// 从Future对象上获取任务的返回值,并输出到控制台
			System.out.println(">>>" + f.get().toString());
		}

		Date date2 = new Date();
		System.out.println("----程序结束运行----,程序运行时间【" + (date2.getTime() - date1.getTime()) + "毫秒】");
	}
}

class MyCallable3 implements Callable<Object> {
	private String taskNum;

	MyCallable3(String taskNum) {
		this.taskNum = taskNum;
	}

	public Object call() throws Exception {
		System.out.println(">>>" + taskNum + "任务启动");
		Date dateTmp1 = new Date();
		Thread.sleep(1000);
		Date dateTmp2 = new Date();
		long time = dateTmp2.getTime() - dateTmp1.getTime();
		System.out.println(">>>" + taskNum + "任务终止");
		return taskNum + "任务返回运行结果,当前任务时间【" + time + "毫秒】";
	}
}

 

 

线程就先复习到这吧,手里还有点任务,表示并不想加班,所以没写那么细

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

标签:

版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有

上一篇:java String中的replace(oldChar,newChar) replace(CharSequence

下一篇:Adobe Acrobat pro生成PDF模版