线程同步

Java编程语言内置了两种线程同步:

  • 互斥同步
  • 条件同步

在互斥同步中,在一个时间点只允许一个线程访问代码段。

条件同步通过条件变量和三个操作来实现:等待,信号和广播。

生产者/消费者

生产者/消费者是使用 wait()notify() 方法的典型线程同步问题。

示例

有四个类:缓冲区,生产者,消费者和主类。

Buffer类的一个对象具有一个整数数据元素,它将由生产者生成并由消费者消费。

我们必须同步对缓冲区的访问,因此只有当缓冲区为空时,生产者才产生一个新的数据元素,而消费者只有在可用时才消耗缓冲区的数据。

import java.util.Random;
public class Main {
    public static void main(String[] args) {
        Buffer buffer = new Buffer();
        Producer p = new Producer(buffer);
        Consumer c = new Consumer(buffer);
        p.start();
        c.start();
    }
}
class Buffer {
    private int data;
    private boolean empty;
    Buffer() {
        this.empty = true;
    }
    synchronized void produce(int newData) {
        while (!this.empty) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.data = newData;
        this.empty = false;
        this.notify();
        System.out.println("Produced:" + newData);
    }
    synchronized int consume() {
        while (this.empty) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        this.empty = true;
        this.notify();
        System.out.println("Consumed:" + data);
        return data;
    }
}
class Producer extends Thread {
    private Buffer buffer;
    Producer(Buffer buffer) {
        this.buffer = buffer;
    }
    public void run() {
        Random rand = new Random();
        while (true) {
            int n = rand.nextInt();
            buffer.produce(n);
        }
    }
}
class Consumer extends Thread {
    private Buffer buffer;
    Consumer(Buffer buffer) {
        this.buffer = buffer;
    }
    public void run() {
        int data;
        while (true) {
            data = buffer.consume();
        }
    }
}

MIT Licensed | Copyright © 2018-present 滇ICP备16006294号

Design by Quanzaiyu | Power by VuePress