synchronizd可以作用于代码块和方法块上,现在编写一个生产者和消费者的简单例子。
功能:
- 两个线程A,B。对同一个List进行操作。A写入数据,B读取数据。
- A每次写入一个数据,就会通知B去读取。
- B每次读取完,就将该数据从List中清除。
- 当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();
}
}