創建線程的四種方式

1.繼承於Thread類,重寫run()方法;
2.實現Runable接口,實現裏面的run()方法;
前兩種不用多說
3.使用 FutureTask 實現有返回結果的線程,可以返回線程執行結果

public class Test {
  public static void main(String[] args) throws InterruptedException, ExecutionException {
    FutureTask<Double> task = new FutureTask(new MyCallable());
    //創建一個線程,異步計算結果
    Thread thread = new Thread(task);
    thread.start();
    //主線程繼續工作
    Thread.sleep(1000);
    System.out.println("主線程等待計算結果...");
    //當需要用到異步計算的結果時,阻塞獲取這個結果
    Double d = task.get();
    System.out.println("計算結果是:"+d);
    //用同一個 FutureTask 再起一個線程
    Thread thread2 = new Thread(task);
    thread2.start();
	}
}
class MyCallable implements Callable<Double>{
    @Override
    public Double call() {
         double d = 0;
         try {
             System.out.println("異步計算開始.......");
              d = Math.random()*10;
             d += 1000;
            Thread.sleep(2000);
             System.out.println("異步計算結束.......");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return d;
    }
}

4.使用ExecutorService、Executors 線程池。

public class MyTest {
    public static void main(String[] args) {
         //創建一個只有一個線程的線程池
         ExecutorService executorService = Executors.newFixedThreadPool(3);
         //創建任務,並提交任務到線程池中
         executorService.execute(new MyRunable("任務1"));
         executorService.execute(new MyRunable("任務2"));
         executorService.execute(new MyRunable("任務3"));
    }
}

class MyRunable implements Runnable{
    private String taskName;
    public MyRunable(String taskName) {
        this.taskName = taskName;
    }
    @Override
    public void run() {
        System.out.println("線程池完成任務:"+Thread.currentThread().getName()+taskName);
    }
}

二、關於run()方法的思考
看看下面這種情況:線程類Thread 接收了外部任務,同時又用匿名內部類的方式重寫了內部的run()方法,這樣豈不是有兩個任務,那麼究竟會執行那個任務呢?還是兩個任務一起執行呢?

public class TestNeibu{
	public static void main(String[] args) {
		Thread thread = new Thread(new MyTask()){
	        @Override
	        public void run() {//重寫Thread類的run方法
	            System.out.println("Thread 類的run方法");
	        }
	    };
	    //線程啓動
	    thread.start();
	}
	
}
class MyTask implements Runnable{
    //重寫run方法
    @Override
    public void run() {
        //任務內容....
        System.out.println("這是Runnable的run方法");
    }
}

運行結果如下:

Thread 類的run方法

Thread類的run方法在沒有重寫的情況下,是判斷一下是否有Runnable 對象傳進來,如果有,那麼就調用Runnable 對象裏的run方法;否則,就什麼都不幹,線程結束。所以,針對上面的例子,一旦你繼承重寫了Thread類的run()方法,而你又想可以接收Runable類的對象,那麼就要加上super.run(),執行沒有重寫時的run方法,改造如下

		Thread thread = new Thread(new MyTask()){
	        @Override
	        public void run() {//重寫Thread類的run方法
	           //調用父類Thread的run方法,即沒有重寫時的run方法
	            super.run();
	            System.out.println("Thread 類的run方法");
	        }
	    };
	    thread.start();
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章