Java 線程詳解

java使用線程的兩種方法:

1.繼承Thread

2.實現Runnable

線程中的一些方法:

wait():  

        Object類的方法,對此對象調用wait方法導致本線程放棄對象鎖,進入等待此對象的等待鎖定池,只有針對此對 象發出notify方法(或notifyAll)後本線程才進入對象鎖定池準備獲得對象鎖進入運行狀態。

sleep:

        是線程類(Thread)的方法,導致此線程暫停執行指定時間,給執行機會給其他線程,但是監控狀態依然保持,到時後會自動恢復。調用sleep不會釋放對象鎖。

yield:

        稱爲“退讓”,它把運行機會讓給了同等優先級的其他線程,就是使當前運行着線程讓出CPU資源,但是讓給誰不知道,僅僅是讓出,線程狀態回到可運行狀態,有可能自己剛讓出,自己馬上又繼續執行了。

   setDaemon(true):

此方法是將線程設置成守護進程。守護線程使用的情況較少,但並非無用,舉例來說,JVM的垃圾回收、內存管理等線程都是守護線程。有什麼用呢?當剩下的進程都是守護進程時,java虛擬機就會退出了,也就是說當非守護線程都執行完了,這個守護線程即便還沒執行完,也會隨着最後一個非守護進程結束而結束!

線程同步:

1.在方法上加上:synchronized  當兩個併發線程訪問同一個對象object中的這個方法時,一個時間內只能有一個線程得到執行。另一個線程必須等待當前線程執行完這個代碼塊以後才能執行該代碼塊。

     如:public synchronized void test(){...}

2.同步代碼塊:synchronized(Object){...}


注意:那麼synchronized鎖住的是代碼還是對象呢?

    synchronized鎖住的是括號裏的對象,而不是代碼。對於非static的synchronized方法,鎖的就是對象本身也就            是this。

看下面一段代碼:

package com.liang.ThreadDemo;

public class SynchronizedTest implements Runnable{
	
	@Override
	public void run() {
		 synchronized(this){ 
             for (int i = 0; i < 5; i++) {  
                  System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);  
             }  
        }  
	}
	public static void main(String[] args) {
		SynchronizedTest t1 = new SynchronizedTest();
		SynchronizedTest t2 = new SynchronizedTest();
		Thread ta = new Thread(t1,"A");
		Thread tb = new Thread(t2,"B");
		ta.start();
		tb.start();
	}
}
結果如下:這怎麼沒有鎖住呢?因爲鎖定是對象,而非代碼,但是不同的對象時就鎖不住了!
A synchronized loop 0
B synchronized loop 0
A synchronized loop 1
B synchronized loop 1
A synchronized loop 2
B synchronized loop 2
A synchronized loop 3
B synchronized loop 3
A synchronized loop 4
B synchronized loop 4

想鎖住很簡單,直接鎖定這個類不就行了:

<span style="color:#362e2b;">package com.liang.ThreadDemo;

public class SynchronizedTest implements Runnable{
	
	@Override
	public void run() {
		 synchronized(</span><span style="color:#ff6666;">SynchronizedTest.class</span><span style="color:#362e2b;">){ 
             for (int i = 0; i < 5; i++) {  
                  System.out.println(Thread.currentThread().getName() + " synchronized loop " + i);  
             }  
        }  
	}
	public static void main(String[] args) {
		SynchronizedTest t1 = new SynchronizedTest();
		SynchronizedTest t2 = new SynchronizedTest();
		Thread ta = new Thread(t1,"A");
		Thread tb = new Thread(t2,"B");
		ta.start();
		tb.start();
	}
}</span>

A synchronized loop 0
A synchronized loop 1
A synchronized loop 2
A synchronized loop 3
A synchronized loop 4
B synchronized loop 0
B synchronized loop 1
B synchronized loop 2
B synchronized loop 3
B synchronized loop 4

只改了紅色的部分,就是鎖住怎個類了,當然加在方法上的,若把方法改成static靜態類,那麼也是鎖住怎個類。













發佈了132 篇原創文章 · 獲贊 41 · 訪問量 110萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章