為瞭解決程式因佔用資源,出現資源爭搶,而出現的程式進入等待的狀態(死結)。
解決這種問題:
我們可以給資源加上“鎖”,在每次調用前進行判斷當前鎖的狀態,再進行執行。
下面是類比程式:
package com.yxy.thread;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;import java.util.Random;/** * @author windows * 安全鎖例子 */public class Safelock { /** * @author windows * 朋友實體類 */ static class Friend { //朋友類,鎖(重入鎖) private final String name; private final Lock lock = new ReentrantLock(); //朋友構造方法 public Friend(String name) { this.name = name; } //擷取名字 public String getName() { return this.name; } //在鞠躬前的判斷 public boolean impendingBow(Friend bower) { //當前我的狀態鎖,與朋友的狀態鎖 Boolean myLock = false; Boolean yourLock = false; try { //記錄當前類的鎖,和鞠躬的朋友的鎖的狀態 myLock = lock.tryLock(); yourLock = bower.lock.tryLock(); } finally { //如果當前類的鎖,與鞠躬朋友的類的狀態,其中有一個為false時 if (! (myLock && yourLock)) { //判斷是那個狀態為true的,對這個鎖進行解鎖。 if (myLock) { lock.unlock(); } if (yourLock) { bower.lock.unlock(); } } } //返回結果 return myLock && yourLock; } /** * @param bower * 向朋友鞠躬的方法 */ public void bow(Friend bower) { //判斷是否有鎖 if (impendingBow(bower)) { //朋友鞠躬時,我沒有鞠躬。列印出資訊,並回敬。 try { System.out.format("%s: %s has" + " bowed to me!%n", this.name, bower.getName()); bower.bowBack(this); } finally { lock.unlock(); bower.lock.unlock(); } } else { //朋友鞠躬的同時我也鞠躬。列印出資訊。 System.out.format("%s: %s started" + " to bow to me, but saw that" + " I was already bowing to" + " him.%n", this.name, bower.getName()); } } /** * @param bower * 回敬鞠躬的方法。 */ public void bowBack(Friend bower) { System.out.format("%s: %s has" + " bowed back to me!%n", this.name, bower.getName()); } } /** * @author windows * 迴圈鞠躬的線程 */ static class BowLoop implements Runnable { //相互鞠躬的兩個人 private Friend bower; private Friend bowee; //構造方法 public BowLoop(Friend bower, Friend bowee) { this.bower = bower; this.bowee = bowee; } //線程的執行方法 public void run() { Random random = new Random(); for (;;) {//無限迴圈。 try { //進程中斷 Thread.sleep(random.nextInt(5)); } catch (InterruptedException e) {} //bowee向bower鞠躬 bowee.bow(bower); } } } //測試 public static void main(String[] args) { final Friend alphonse = new Friend("Alphonse"); final Friend gaston = new Friend("Gaston"); new Thread(new BowLoop(alphonse, gaston)).start(); new Thread(new BowLoop(gaston, alphonse)).start(); }}