生产者和消费者的简单例子

时间:2021-12-08 20:48:21

synchronizd可以作用于代码块方法块上,现在编写一个生产者和消费者的简单例子。

功能:

  1. 两个线程A,B。对同一个List进行操作。A写入数据,B读取数据。
  2. A每次写入一个数据,就会通知B去读取。
  3. B每次读取完,就将该数据从List中清除。
  4. 当List为空的时候,B会一直等待。

下面是详细代码:

package com.test;

import java.util.ArrayList;
import java.util.List;

/**
* Created by laiwenqiang on 2017/5/22.
*/

public class ThreadTest {

List list = new ArrayList();

public static void main(String[] args) throws InterruptedException {
final ThreadTest test = new ThreadTest();

Runnable runnable01 = new Runnable() {
@Override
public void run() {
test.add("hello");
test.add("world");
}
};

Runnable runnable02 = new Runnable() {
@Override
public void run() {
while (true) {
test.get();
}
}
};

new Thread(runnable01).start();
new Thread(runnable02).start();
}

public synchronized void add(String string) {
list.add(string);
notifyAll();
}

public synchronized void get() {
while (list.isEmpty()) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("length: " + list.size());
System.out.println(list.get(0));
list.remove(0);
}
}

add是写方法,get是读方法。

我们用synchronized修饰这两个方法。

add方法会调用notifyAll,去唤醒在等待中的get方法。

当然,这两个方法也可以这么写:

public void get() {
synchronized (list) {
while (list.isEmpty()) {
try {
list.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("length: " + list.size());
System.out.println(list.get(0));
list.remove(0);
}
}

public void add(String str) {
synchronized (list) {
list.add(str);
list.notifyAll();
}
}