1. 程式人生 > >併發程式設計的三種實現方式

併發程式設計的三種實現方式

java天生就是多執行緒的程式語言,建立新的執行緒有三種實現方式,分別是:

繼承Thread,實現Runable,實現Callable<T>

程式碼如下:

//Thread
class ThreadTest extends Thread {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		
	}

}
//Callable
class CallableTest implements Callable<String> {

	@Override
	public String call() throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

}
//Runnable
class RunableTest implements Runnable {

	@Override
	public void run() {
		// TODO Auto-generated method stub

	}

}

三種方式又分別有自己的啟動方式

package com.hyan.client;

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

public class Test {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		// Thread執行
		ThreadTest threadTest = new ThreadTest();

		threadTest.start();
		Thread.sleep(50);
		threadTest.interrupt();
		// Callable執行
		CallableTest callableTest = new CallableTest();
		FutureTask<String> futureTask = new FutureTask<>(callableTest);
		Thread thread = new Thread(futureTask);
		thread.start();
		Thread.sleep(50);
		thread.interrupt();
		System.out.println("callable的返回值:" + futureTask.get());
		// Runnable執行
		RunableTest runableTest = new RunableTest();
		Thread runThread = new Thread(runableTest);
		runThread.start();
		Thread.sleep(50);
		runThread.interrupt();
	}

}

class ThreadTest extends Thread {

	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();

		System.out.println(Thread.currentThread().getName() + ">1>>>>>>>>>" + isInterrupted());
		while (!isInterrupted()) {
			try {
				Thread.sleep(20);
				System.out.println(Thread.currentThread().getName() + ">1>>>>>>>>>run");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				// 需要在catch中再次呼叫interrupt,這樣才能終止while
				interrupt();
			}

		}
		// isInterrupted()是例項方法,是呼叫該方法的物件所表示的那個執行緒的isInterrupted(),不會重置當前執行緒的中斷狀態
		System.out.println(Thread.currentThread().getName() + ">1>>>>>>end" + isInterrupted());
		// interrupted()是靜態方法:內部實現是呼叫的當前執行緒的isInterrupted(),並且會重置當前執行緒的中斷狀態
		Thread.interrupted();

		System.out.println(Thread.currentThread().getName() + ">1>>>>>>end改變後的狀態" + isInterrupted());

	}

}

class CallableTest implements Callable<String> {

	@Override
	public String call() throws Exception {
		// TODO Auto-generated method stub

		while (!Thread.currentThread().isInterrupted()) {
			try {
				Thread.sleep(20);
				System.out.println(Thread.currentThread().getName() + ">2>>>>>>>>>run");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				Thread.currentThread().interrupt();
			}

		}
		System.out.println(Thread.currentThread().getName() + ">2>>>>>>end" + Thread.currentThread().isInterrupted());
		return "CallableTest end ";
	}

}

class RunableTest implements Runnable {

	@Override
	public void run() {
		// TODO Auto-generated method stub

		while (!Thread.currentThread().isInterrupted()) {
			try {
				Thread.sleep(20);
				System.out.println(Thread.currentThread().getName() + ">3>>>>>>>>>run");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				Thread.currentThread().interrupt();
			}

		}
		System.out.println(Thread.currentThread().getName() + ">3>>>>>>end" + Thread.currentThread().isInterrupted());

	}

}

如果要終止一個執行緒,可以使用stop()方法,但是已經被棄用,現在應該使用interrupt來終止執行緒的執行;

開發過程中可以通過interrupt方法改變中斷狀態,線上程中捕捉執行緒的中斷狀態,當isInterrupted()為true時,代表中斷執行緒,但是具體的實現程式碼還需要自己去中斷。

注:

interrupt方法改變中斷狀態也就是isInterrupted()變為true

isInterrupted()判斷執行緒是否需要中斷

interrupted()為靜態方法,用來恢復執行緒的中斷狀態,也就是將isInterrupted()變為false;

Thread-0>1>>>>>>>>>false
Thread-0>1>>>>>>>>>run
Thread-0>1>>>>>>>>>run
Thread-0>1>>>>>>endtrue
Thread-0>1>>>>>>end改變後的狀態false
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.hyan.client.ThreadTest.run(Test.java:44)
Thread-1>2>>>>>>>>>run
Thread-1>2>>>>>>>>>run
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.hyan.client.CallableTest.call(Test.java:73)
	at com.hyan.client.CallableTest.call(Test.java:1)
	at java.util.concurrent.FutureTask.run(Unknown Source)
	at java.lang.Thread.run(Unknown Source)
Thread-1>2>>>>>>endtrue
callable的返回值:CallableTest end 
Thread-2>3>>>>>>>>>run
Thread-2>3>>>>>>>>>run
java.lang.InterruptedException: sleep interrupted
	at java.lang.Thread.sleep(Native Method)
	at com.hyan.client.RunableTest.run(Test.java:96)
	at java.lang.Thread.run(Unknown Source)
Thread-2>3>>>>>>endtrue

當子執行緒中包含了等待,在InterruptedException中應該再次呼叫interrupt方法,這樣才能終止執行緒