1. 程式人生 > >執行緒的死鎖與執行緒的通訊

執行緒的死鎖與執行緒的通訊

產生背景

不同執行緒分別佔用對方需要的同步資源部放棄,都在等待對方放棄自己需要的同步資源,形成了執行緒的死鎖

解決方法

專門的演算法,原則

儘量減少同步資源的定義

案例

package com.zyd.thread;

public class TestDeadLock {
    static StringBuilder sb1 = new StringBuilder();
    static StringBuilder sb2 = new StringBuilder();
    public static void main (String[] args)
{ new Thread(){ public void run(){ synchronized (sb1){ try { Thread.currentThread().sleep(10); } catch (InterruptedException e) { e.printStackTrace(); }
sb1.append("A"); synchronized (sb2){ sb2.append("B"); System.out.println(sb1); System.out.println(sb2); } } } }
.start(); new Thread(){ public void run(){ synchronized (sb2){ try { Thread.currentThread().sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } sb1.append("C"); synchronized (sb1){ sb2.append("D"); System.out.println(sb1); System.out.println(sb2); } } } }; } }

執行緒的通訊

定義在Object裡面

wait():令當前執行緒掛起並放棄CPU,同步資源,使別的執行緒可訪問並修改共享資源,而當前執行緒排隊等待再次對資源的訪問

notify():喚醒正在排隊等待同步資源的執行緒中優先順序最高者結束等待

notifyAll():喚醒正在排隊等待資源的所有執行緒結束等待

注意:

這桑方法只有在synchronized方法或synchronized程式碼塊中才能使用,否則報錯

java.lang.IllegalMonitorStateException異常

案例:使用兩個執行緒列印 1-100. 執行緒1, 執行緒2 交替列印

package com.zyd.thread;

 class PrintNum implements Runnable {
    int num = 1;
    Object obj = new Object();
    @Override
    public void run() {
        while (true){
            synchronized (obj){
                obj.notify();
                if (num <= 100){
                    try {
                        Thread.currentThread().sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+":"+num);
                    num++;
                }else {
                    break;
                }
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
public class TestCommunication{
     public static void main (String[] args){
             PrintNum p = new PrintNum();
         Thread t1 = new Thread(p);
         Thread t2 = new Thread(p);

         t1.setName("A:");
         t2.setName("B");
         t1.start();
         t2.start();
     }
}