1. 程式人生 > 其它 >Java多執行緒(六)-執行緒通訊

Java多執行緒(六)-執行緒通訊

七.執行緒通訊

在生產者與消費者問題中,生產者和消費者共享同一個資源,且二者之間相互依賴,互為條件。

  • 對於生產者,沒有生產產品前,要通知消費者等待,生產之後要通知消費者消費。
  • 對於消費者,消費之後要通知生產者生產新產品以供消費
  • synochronized可阻止併發更新同一個共享資源,實現同步。但不能實現執行緒之間通訊。

解決方法:

1.管程法:生產者將生產的資料放入緩衝區,消費者從緩衝取取出資料

點選檢視程式碼
public class guancheng {
    public static void main(String[] args) {
        Container container = new Container();
        new Productor(container).start();
        new Consumer(container).start();
    }
}

//產品
class Product{

    int id;

    public Product(int id) {
        this.id = id;
    }
}

//消費者
class Consumer extends Thread{

    Container container;

    public Consumer(Container container){
        this.container = container;
    }

    @Override
    public void run() {
        // 消費
        for (int i = 0; i < 100; i++) {
            Product product = container.pop();
            System.out.println("消費了第"+product.id+"個產品");
        }
    }
}

//生產者
class Productor extends Thread{

    Container container;

    public Productor(Container container){
        this.container = container;
    }

    @Override
    public void run() {
        // 生產
        for (int i = 0; i < 100; i++) {
            container.push(new Product(i));
            System.out.println("生產了第"+i+"個產品");
        }
    }
}

//緩衝區
class Container{

    Product[] products = new Product[100];
    // 定義容器大小
    int count = 0;

    public synchronized void push(Product product){
        // 生產者生產產品
        if (count == products.length){
            // 容器滿了,通知消費者消費,停止生產
        }
        products[count] = product;
        // 沒有滿,生產者生產產品
        count++;
    }

    public synchronized Product pop(){
        // 消費者消費產品
        if (count == 0){
            // 沒有產品,通知生產者生產
        }
        count--;
        // 消費者消費
        Product product = products[count];
        return product;
    }
}

2.訊號燈法:設定標誌位

點選檢視程式碼
public class xinhaodeng {
    public static void main(String[] args) {
        Show show = new Show();
        new Player(show).start();
        new Audience(show).start();
    }
}

// 生產者
class Player extends Thread{

    Show show;

    public Player(Show show){
        this.show = show;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            if (i%2==0){
                show.act("news->"+i);
            }else {
                show.act("movie->"+i);
            }
        }
    }
}

// 消費者
class Audience extends Thread{

    Show show;

    public Audience(Show show){
        this.show = show;
    }

    @Override
    public void run() {
        for (int i = 0; i < 10; i++) {
            show.watch();
        }
    }
}

// 產品
class Show{

    String show;
    boolean flag = true;
    // 表演者表演,觀眾等待true
    // 觀眾觀看,表演者等待false

    public synchronized void act(String show){
        if (!flag){
            // 觀眾觀看,表演者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("表演者表演了"+show);
        this.notifyAll();
        // 通知觀眾觀看
        this.show = show;
        this.flag = !this.flag;
    }

    public synchronized void watch(){
        if (flag){
            // 表演者表演,觀眾等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("觀眾觀看了"+show);
        this.notifyAll();
        // 通知表演者表演
        this.flag = !this.flag;
    }
}