java.util.concurrent包(3)——線程間通訊wait/notify和await/signal

1、線程如何中止安全

使用stop()不安全。它會解除由線程獲取的全部鎖定,並且若是對象處於一種不連貫狀態,那麼其餘線程能在那種狀態下檢查和修改它們。結果很難檢查出真正的問題所在。suspend()方法容易發生死鎖。調用suspend()的時候,目標線程會停下來,但卻仍然持有在這以前得到的鎖定。此時其餘任何線程都不能訪問鎖定的資源,除非被"掛起"的線程恢復運行。對任何線程來講,若是它們想恢復目標線程,同時又試圖使用任何一個鎖定的資源,就會形成死鎖。因此不該該使用suspend()。正確的作法是而應在本身的Thread類中置入一個標誌,指出線程應該活動仍是掛起。若標誌指出線程應該掛起,便用wait()命其進入等待狀態。若標誌指出線程應當恢復,則用一個notify()從新啓動線程。jdk1.5後提供了condition對象,這個對象的await()和singal()方法也能夠達到線程通訊的效果。ide


2、wait和notify實例oop

子線程循環10次,主線程循環100次。接着子線程循環10次,主線程循環100次。如此循環50次。摘自張孝祥老師線程視頻源碼。this

public class TraditionalThreadCommunicationspa

{線程

public static void main(String[] args)視頻

{對象

final Business business = new Business();資源

new Thread(new Runnable() {源碼

public void run()

{

for (int i = 1; i <= 50; i++)

{

business.sub(i);

}

}

}).start();

for (int i = 1; i <= 50; i++)

{

business.main(i);

}

}

}

class Business

{

private boolean bShouldSub = true;

public synchronized void sub(int i)

{

while (!bShouldSub)

{

try

{

this.wait();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 10; j++)

{

System.out.println("sub thread sequence of " + j + ",loop of " + i);

}

bShouldSub = false;

this.notify();

}


public synchronized void main(int i)

{

while (bShouldSub)

{

try

{

this.wait();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 100; j++)

{

System.out.println("main thread sequence of " + j + ",loop of " + i);

}

bShouldSub = true;

this.notify();

}

}


3、Condition實例

public class Condition1Test

{

public static void main(String[] args)

{

final BusinessLock business = new BusinessLock();

new Thread(new Runnable() {

public void run()

{

for (int i = 1; i <= 50; i++)

{

business.sub(i);

}

}

}).start();

for (int i = 1; i <= 50; i++)

{

business.main(i);

}

}

}

class BusinessLock

{

private boolean bShouldSub = true;

ReentrantLock lock = new ReentrantLock();

Condition condition = lock.newCondition();


public void sub(int i)

{

lock.lock();

try

{

while (!bShouldSub)

{

try

{

condition.await();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 10; j++)

{

System.out.println("sub thread sequence of " + j + ",loop of " + i);

}

bShouldSub = false;

condition.signal();

}

finally

{

lock.unlock();

}

}


public void main(int i)

{

lock.lock();

try

{

while (bShouldSub)

{

try

{

condition.await();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 100; j++)

{

System.out.println("main thread sequence of " + j + ",loop of " + i);

}

bShouldSub = true;

condition.signal();

}

finally

{

lock.unlock();

}

}

}


4、Condition實例擴展

三個線程相互通訊,main循環100次,sub2循環10次,sub3循環10次。接着main循環100次,sub2循環10次,sub3循環10次。如此循環50次。

public class Condition2Test

{

public static void main(String[] args)

{

final BusinessLock2 business = new BusinessLock2();

new Thread(new Runnable() {

public void run()

{

for (int i = 1; i <= 50; i++)

{

business.main(i);

}

}

}).start();


new Thread(new Runnable() {

public void run()

{

for (int i = 1; i <= 50; i++)

{

business.sub2(i);

}

}

}).start();


new Thread(new Runnable() {

public void run()

{

for (int i = 1; i <= 50; i++)

{

business.sub3(i);

}

}

}).start();

}

}


class BusinessLock2

{

private int bShouldSub = 1;

ReentrantLock lock = new ReentrantLock();

Condition condition1 = lock.newCondition();

Condition condition2 = lock.newCondition();

Condition condition3 = lock.newCondition();


public void main(int i)

{

lock.lock();

try

{

while (bShouldSub != 1)

{

try

{

condition1.await();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 100; j++)

{

System.out.println("main thread sequence of " + j + ",loop of " + i);

}

bShouldSub = 2;

condition2.signal();

}

finally

{

lock.unlock();

}

}


public void sub2(int i)

{

lock.lock();

try

{

while (bShouldSub != 2)

{

try

{

condition2.await();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 10; j++)

{

System.out.println("sub2 thread sequence of " + j + ",loop of " + i);

}

bShouldSub = 3;

condition3.signal();

}

finally

{

lock.unlock();

}

}


public void sub3(int i)

{

lock.lock();

try

{

while (bShouldSub != 3)

{

try

{

condition3.await();

}

catch (InterruptedException e)

{

e.printStackTrace();

}

}

for (int j = 1; j <= 10; j++)

{

System.out.println("sub3 thread sequence of " + j + ",loop of " + i);

}

bShouldSub = 1;

condition1.signal();

}

finally

{

lock.unlock();

}

}

}

相關文章
相關標籤/搜索