Java建立線程方式

     關於線程的內容不少,非一朝一夕可以說完的,java中關於多線程的內容也很多,不要只停留在Thread類和Runnable接口的層面,可是今天簡單體驗Java多線程,主要圍繞Thread和Runnable展開。java

     1.首先明確一個概念,在java裏面一個線程只能啓動一次,不然會拋異常的。一個死亡的線程是沒有再次獨立運行的能力。多線程

     2.線程的幾種狀態。異步

     線程包含以下幾個狀態:初始化、就緒、運行、阻塞、死亡。ide

     下面簡單的描述如下這幾個狀態。spa

      初始化:建立的Thread類或者其子類對象;線程

      就緒:已經完成建立而且初始化的線程對象,而且已經調用start方法了,可是沒有獲取到運行所需的資源(如cup、內存、IO等等)。在java程序中,就是調用了start方法,可是尚未執行run方法的狀態。code

      運行:線程對象獲取到了運行所需的資源,而且正在執行任務代碼。對象

      阻塞:當前線程仍然是活的,也是能夠運行的,可是缺乏運行的條件,一旦某個事件出現,可以從當前狀態轉爲就緒狀態。(實際上,在這裏描述的仍是太簡單了,在日後的筆記中會詳細說一說這個狀態包含的幾種形態)繼承

      死亡:run方法已經執行完了,再也不是一個單獨執行任務的線程了。咱們就認爲其死亡了。接口

     3.java中建立線程的幾種方式。

     在Java裏面建立線程有三種方式。具體以下:

    (1)繼承Thread類

    (2)實現Runnable接口

    (3)使用Callable與Future來建立

     接下來,分別簡單介紹這三種方式。

     方式一:繼承Thread類。第一步,繼承Thread類,第二步實現run方法。

 * step1:繼承Thread類
 * step2:重寫run方法
 * @author lingxiasandu
 *
 */
public class MyThread extends Thread {

	@Override
	public void run() {
	    System.out.println("MyThread is runing !");
	}
	
	public static void main(String[] args) {
		  MyThread t = new MyThread();
		  t.start();
	}

	
}

  方法二:實現Runnable接口。

public class MyThread2 implements Runnable {

	@Override
	public void run() {
		System.out.println("MyThread2 is running !");

	}
	
	public static void main(String[] args) {
		MyThread2 runable = new MyThread2();
		//和第一種方式的區別,在於啓動線程時,須要依靠一個Thread對象來start
		Thread t = new Thread(runable);
		t.start();
	}

}

   第三種:是使用了concurrent包下面的Callable與Future。該種方式適合在有返回值的異步任務。

package hq.java.thread.example;

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/***
 * 
 * @author lingxiansandu
 *
 */
public class MyTask implements Callable<Integer> {

	@Override
	public Integer call() throws Exception {
		System.out.println("線程名稱是:"+Thread.currentThread().getName());
		System.out.println("MyTask is runing");
		return 9;
	}
	
	public static void main(String[] args) throws InterruptedException, ExecutionException {
		Callable<Integer> call = new MyTask();
		FutureTask<Integer> future = new FutureTask<Integer>(call);
		Thread t = new Thread(future,"帶返回值的線程");
		t.start();
		System.out.println("線程返回值是:"+future.get());
	}

}

4.建立並啓動線程常見的寫法。

  在實際項目種常見的寫法有如下幾種:

   (1)使用匿名類的方式,適用在只有一個地方適用run方法內部的代碼,複用率低的地方。

   代碼以下:

new Thread(new Runnable() {
			
			@Override
			public void run() {
			  System.out.println("線程運行了!");
				
			}
		}).start();

    (2)實現Runnable接口,新增一個start方法。這種方式使用於複用率較高的地方,讓使用者忽略線程內部實現,只須要調用start方法就好了。舉個例子,系統在交易時發生異常的時候,向監控平臺發報告,就可使用這種方式。

public class CreateThreadExample {
    public static void main(String[] args) {
    	SendMoniter.send("1001", "轉帳丟失");
	}
}

class SendMoniter implements Runnable{
    private String errorMsg;
	private String tranId;
	@Override
	public void run() {
		System.out.println("報告監控平臺,交易"+tranId+"有錯誤,錯誤爲:"+errorMsg);
	}
	
	
	
	public static void send(String tranId,String errorMsg){
		SendMoniter moniter = new SendMoniter();
		moniter.errorMsg = errorMsg;
		moniter.tranId = tranId;
		Thread t = new Thread(moniter);
		t.start();
	}
	
}


   5.線程睡眠的兩種方式。

    (1)Thread.sleep(100);

    (2) TimeUnit.MILLISECONDS.sleep(1000);//(推薦使用這種)

相關文章
相關標籤/搜索