线程的同步机制有两种实现方法:
- 使用synchronized关键字,Object类的wait()、notify()、notifyAll()方法。
- 使用并发包的Lock接口及其实现类,Condition类的await()、signal()、signalAll()方法。
下面分别实现。
第一种方式:
public class P_C {
private final static Object object = new Object();
private static int num = 0;
public static void main(String[] args) throws InterruptedException {
Producer producer = new Producer("生产者");
Consumer consumer = new Consumer("消费者");
producer.start();
Thread.sleep(500);
consumer.start();
}
private static int getN() {
return num;
}
private static void setN(int n) {
num = n;
}
/**
* 生产者
* */
private static class Producer extends Thread {
public Producer(String name) {
super(name);
}
@Override
public void run() {
while (true) {
synchronized (object) {
int n = new Random().nextInt(20);
setN(n);
System.out.println(Thread.currentThread().getName() + " 生产: " + n);
object.notify();
try {
Thread.sleep(1000);
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
/**
* 消费者
* */
private static class Consumer extends Thread {
public Consumer(String name) {
super(name);
}
@Override
public void run() {
while (true) {
synchronized (object) {
int n = getN();
System.out.println(Thread.currentThread().getName() + " 消费: " + n);
object.notify();
try {
Thread.sleep(1000);
object.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
第二种方式:
public class P_C {
private final static Lock lock = new ReentrantLock();
private final static Condition condition = lock.newCondition();
private static int num = 0;
public static void main(String[] args) throws InterruptedException {
Producer producer = new Producer("生产者");
Consumer consumer = new Consumer("消费者");
producer.start();
Thread.sleep(500);
consumer.start();
}
private static int getN() {
return num;
}
private static void setN(int n) {
num = n;
}
/**
* 生产者
*/
private static class Producer extends Thread {
Producer(String name) {
super(name);
}
@Override
public void run() {
while (true) {
try {
lock.lock();
int n = new Random().nextInt(20);
setN(n);
System.out.println(Thread.currentThread().getName() + " 生产: " + n);
condition.signal();
try {
Thread.sleep(1000);
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
/**
* 消费者
*/
private static class Consumer extends Thread {
Consumer(String name) {
super(name);
}
@Override
public void run() {
while (true) {
try {
lock.lock();
int n = getN();
System.out.println(Thread.currentThread().getName() + " 消费: " + n);
condition.signal();
try {
Thread.sleep(1000);
condition.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
}
}