1. 程式人生 > >【線程間通信:等待喚醒機制】

【線程間通信:等待喚醒機制】

runnable lean ride system not 必須 this 消費者 clas

在線程安全解決之後,還是一樣存在著如下的問題:

A:如果消費者先搶到CPU的執行權,就會去消費數據,但是現在的數據是默認值,沒有意義,應該等著數據有意義,再消費。

B:如果生產者先搶到CPU的執行權,就會去生產數據,但是呢,它生產完數據後,還繼續擁有執行權,它又繼續產生數據。這是有問題的,它應該等著消費者把數據消費掉,然後再生產。

正常的思路:

A:生產者:先看是否有數據,有就等待,沒有就生產,生產完後通知消費者來消費數據。

B:消費者:先是是否有數據,有就消費,沒有就等待,通知生產者生產數據。

為了處理這樣的問題,JAVA就提供了一種機制,等待喚醒機制。

等待喚醒: Object 類中提供了三個方法:

  wait():等待

  notify():喚醒單個線程

  notifyAll():喚醒所有線程

為什麽這些方法不定義在Thread類中呢?

  這些方法的調用必須通過鎖對象調用,要所有鎖對象都可以調用的話,方法就應該在他們共有的父類上,也就是Object類。

例子:線程間通信:生產者消費者(等待喚醒機制)

package com.test;

public class Student {

    String name;
    int age;
    boolean isTrue;

    public synchronized void set(String name, int
age) { /**如果有數據,就等待*/ if (this.isTrue) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } /**設置數據*/ this.name = name; this.age = age; /**修改標記*/ this
.isTrue = true; this.notify(); } public synchronized void get() { /**如果沒有數據,就等待*/ if (!this.isTrue) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } /**獲取數據*/ System.out.println(this.name + "---" + this.age); /**修改標記*/ this.isTrue = false; this.notify(); } }
package com.test;

public class SetThread implements Runnable {

    private Student s;
    private int x = 0;

    public SetThread(Student s) {
        this.s = s;
    }

    @Override
    public void run() {
        while (true) {

            if (x % 2 == 0) {
                s.set("葉胖子", 27);
            } else {
                s.set("王瘦子", 31);
            }
            x++;

        }
    }
}
package com.test;

public class GetThread implements Runnable {

    private Student s;

    public GetThread(Student s){
        this.s = s;
    }

    @Override
    public void run() {
        while (true){
            s.get();
        }
    }

}
package com.test;

public class StudentTest {

    public static void main(String[] args) {

        Student s = new Student();

        SetThread st = new SetThread(s);
        GetThread gt = new GetThread(s);

        Thread t1 = new Thread(st);
        Thread t2 = new Thread(gt);

        t1.start();
        t2.start();

    }

}

【線程間通信:等待喚醒機制】