Thread、Runnable、Callable實現線程的方式

一、線程實現的三種方式

  1. 繼承Thread類
  2. 實現Runnable接口
  3. 實現Callable接口,需要實現的是call方法

二、代碼的簡單實現

package cn.xdf.threadpool;

public class RunnableDemo  {
	//1.繼承 Thread方式的線程
	public static class TestThreadDemo extends Thread{
		  @Override
		  public void run() {
			  	  System.out.println(Thread.currentThread().getName()+"--繼承 Thread方式--在運行!");
		  }
	}
	
	//2.1  實現runnable接口方式的線程
	public static class TestRunnableDemo implements Runnable{
		  @Override
		  public void run() {
			    System.out.println(Thread.currentThread().getName()+"--實現runnable接口方式--在運行!");
		  }
	}
	public static void main(String[] args) {
		  //調用1. 繼承 Thread方式
		  TestThreadDemo tt1 = new TestThreadDemo();
		  TestThreadDemo tt2 = new TestThreadDemo();
		  tt1.start();//Thread-0--繼承 Thread方式--在運行!
		  tt2.start();//Thread-1--繼承 Thread方式--在運行!
		
		  //調用2.1 實現runnable接口方式 的
		  TestRunnableDemo t1 = new TestRunnableDemo();
		  TestRunnableDemo t2 = new TestRunnableDemo();
		  new Thread(t1).start();//Thread-2--實現runnable接口方式--在運行!
		  new Thread(t2).start();//Thread-3--實現runnable接口方式--在運行!

		  //調用2.2 new Runnable對象方式
		  Runnable runnable = new Runnable(){
			    @Override
			    public void run() {
				    System.out.println(Thread.currentThread().getName()+"--new Runnable對象方式--在運行!");
			    }
			
		  };
		  new Thread(runnable).start();//Thread-4--new Runnable對象方式--在運行!
		  //這5個線程的調用順序不一定
	  }
}

package cn.xdf.threadpool;

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

public class CallableDemo {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		  //3.2 new Callable方式的實現線程
		  Callable<String> callable = new Callable<String>(){//Callable方式的線程
		  	  @Override
		  	  public String call() throws Exception {
		      		Random random = new Random();
			      	return "返回值爲:"+random.nextInt(200);//根據FutureTask 可以獲取這個返回值!!!
			    }
		  };
		  FutureTask<String> futureTask = new FutureTask<>(callable);//根據FutureTask 獲取返回值
		  new Thread(futureTask).start();//開啓一個線程
		  String result = futureTask.get();//需要拋異常  //根據FutureTask 獲取返回值
		  System.out.println("result:"+result);//result:返回值爲:140
		
		  //3.1 實現Callable接口
		  TestCallableDemo cd1 = new TestCallableDemo();
		  FutureTask<String> ft = new  FutureTask<>(cd1);//根據FutureTask 獲取返回值
		  new Thread(ft).start();//開啓一個線程
		  String rs = ft.get();//需要拋異常   //根據FutureTask 獲取返回值
		  System.out.println("rs:"+rs);//rs:Thread-1--實現Callable接口方式的線程--在運行!
	}
	  //3.1 實現Callable接口
	  public static class TestCallableDemo implements Callable{

		    @Override
		    public String call() throws Exception {
			      String result = Thread.currentThread().getName()+"--實現Callable接口方式的線程--在運行!";
			      return result;
		    }
		
  	 }

}

三、總結:
1.Runnable接口的話,可以避免單繼承的侷限性,具有較強的健壯性。
2.Runnable可以實現資源的共享,同時處理同一資源。
3.Thread類的線程間都是獨立運行的,資源不共享。
4.繼承Thread類不再被其他類繼承(java不存在多繼承)
5.Callable是一個接口,Callable使用call( )方法,可以返回值;Runnable使用run( )方法,沒有返回值。
6.call() 可以拋出受檢查的異常,比如ClassNotFoundException, 而run()不能拋出受檢查的異常

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章