Java多線程總結(未完待續)

1.線程生命週期java

(1) 新建算法

(2)  就緒編程

(3)  運行安全

(4)  阻塞:1.正常切換 2.sleep()方法 3.wait()方法 4.執行某個操做進入阻塞狀態(等待IO、等待某個通知、試圖得到一個同步監視器等)併發

(5)  死亡spa


2.建立線程的方法線程

1)繼承Threadrest

2)實現Runnable接口code

(3)使用Callable和Future建立線程orm

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


public class Main implements Callable<Integer>{

		public static void main(String[] args)
		{
			Main main = new Main();
			
			FutureTask<Integer> task = new FutureTask<Integer>(main);
			
			new Thread(task, "子線程").start();
					
			try {
				System.out.println("子線程返回值:"+ task.get());
			} 
		    catch(Exception e) {
				
				e.printStackTrace();
			}
			
		}

		public Integer call() throws Exception {
			
			int i = 0;
			for(; i < 100; i++)
			{
				System.out.println(Thread.currentThread().getName()+"的變量i的值:"+i);
			}
			return i;
		}
}


比較:Runnable與Callable方式基本相同,只是Callable接口裏定義的方法有返回值,能夠聲明拋出異常而已。

因此暫時將二者歸爲同一種方式。這種方式與繼承Thread類的主要區別爲:

(1)線程實現了Runnable接口,還能夠繼承其餘類

(2)多個線程能夠共享同一個target對象,多個線程共享該對象的成員變量


3.目標對象與線程的關係(後續上代碼解釋)

1)目標對象與線程徹底解耦

2)目標線程組合線程(弱耦合)


4.線程優先級與調度管理

1Java線程的優先級都在常數1~10的範圍內,默認爲5

2setPriorityint)和getPriority()。

3Java調度器的任務是使高優先級的線程能始終運行,一旦時間片有空閒,則使具備同等優先級的線程以輪流的方式順序使用時間片。在實際編程中,不提倡使用線程的優先級來保證算法的正確執行。


5.線程控制方法

(1)sleepint millsecond):單位毫秒

(2)yield():與sleep()方法類似,稱爲線程讓步,使線程暫停,但不會阻塞線程,只是將線程轉入就緒狀態,讓系統的調度器從新調度一次。

與sleep()區別:sleep()方法暫停當前線程,會給其餘線程機會,不理會其餘線程的優先級;但yield()方法只會給有優先級相同或更高的線程執行機會。

sleep()方法將線程轉入阻塞狀態;而yield()方法將線程轉入就緒狀態

3isAlive():檢查線程是否處於運行狀態的方法

注意:一個已經運行的線程在沒有進入死亡狀態時,不要再給線程分配線程實體,因爲線程只能引用最後分配的實體,先前的實體就會變成垃圾,而且不會被垃圾收集器收集。

4interrupt()

(5)join():稱爲線程聯合

一個線程A在佔用CPU資源期間,可讓其餘線程調用join()和本線程聯合,如B.join();

咱們稱A在運行期間聯合了B,若是線程A在佔用CPU資源期間一旦聯合線程B,那麼A線程將馬上中斷執行,一直等到它聯合的線程B執行完畢,線程A再從新排隊等待CPU資源,以便恢復執行。若是A準備聯合的B已經結束,那麼B.join()不會產生任何效果。

(6)setDaemon(boolean on):稱爲後臺線程或守護線程

一個線程調用void setDaemonboolean on)方法能夠將本身設置成一個守護線程。當程序中全部用戶線程已結束運行,即便守護線程的run()方法中還有須要執行的語句,守護線程也馬上結束執行。


 6.線程同步方法

(1)synchronized關鍵字:

synchronized(obj)

{

//同步代碼塊

}

其中obj稱爲同步監視器

(2)同步鎖(Lock)(後續上代碼)


7.線程通訊方法

(1)wait()、notify()、notifyAll():適用於用synchronized修飾的方法或代碼塊

import java.util.Scanner;

public class Main{

	public static void main(String[] args) {

	A a = new A();
	B b = new B();

	Thread aThread = new Thread(a);
	Thread bThread = new Thread(b);

	aThread.start();
	bThread.start();


	while(true)
	{
		Scanner reader = new Scanner(System.in);
		int type = reader.nextInt();
		if(type == 1)
			a.restart();
		else if(type == 2)
			b.restart();
	}

	}
	}
	class A implements Runnable
	{
	int number = 0;

	public void run() {
		
		while(true)
		{
			number++;
			System.out.println(Thread.currentThread().getName()+":number="+number);
			if(number%5 == 0)
			{
				System.out.println(Thread.currentThread().getName()+"掛起");
				try {
					hangUp();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"恢復執行");
				
			}
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
	}

	public synchronized void hangUp() throws InterruptedException
	{
		wait();
	}

	public synchronized void restart()
	{
		notifyAll();
	}
	}


	class B implements Runnable
	{
	int number = 0;

	public void run() {
		
		while(true)
		{
			number--;
			System.out.println(Thread.currentThread().getName()+":number="+number);
			if(number%10 == 0)
			{
				System.out.println(Thread.currentThread().getName()+"掛起");
				try {
					hangUp();
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"恢復執行");
				
			}
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		
	}

	public synchronized void hangUp() throws InterruptedException
	{
		wait();
	}

	public synchronized void restart()
	{
		notifyAll();
	}
}

//控制檯輸入1喚醒子線程aThread,2喚醒子線程bThread

(2)Conditon:程序使用Lock來同步,系統中存在隱式的同步監視器,也就不能用wait()、notify()方法,此時可以使用Condition方法:await()、signal()、signalAll()。

(3)阻塞隊列(BLockingQueue):特別適合於生產者消費者問題


8.線程池:(後續上代碼)

(1)Excutors:

(2)ForkJoinPool:特別適用於多CPU作並行處理


9.線程相關類

(1)ThreadLocal:表明一個線程局部變量,讓每個線程建立該變量的副本,從而避免併發訪問的線程安全問題

(2)使用Collections提供的靜態方法把集合包裝成線程安全的集合,例如:

HashMap h = Collections.synchronizedMap(new HashMap());

(3)ConcurrentHashMap、CopyOnWriteArrayList等

相關文章
相關標籤/搜索