1、实现生产者/消费者模式:一对一交替打印
public class MyService {
private ReentrantLock lock= new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean hasValue = false;
public void set() {
try{
lock.lock();
while (hasValue == true) {
condition.await();
}
System.out.println("----");
hasValue = true;
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void get() {
try {
lock.lock();
while (hasValue == false) {
condition.await();
}
System.out.println("****");
hasValue = false;
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
两个 自定义的线程
public class MyThread1 extends Thread {
private MyService service;
public MyThread1(MyService service) {
this.service = service;
}
@Override
public void run() {
for (int i=0; i<100; i++) {
service.set();
}
}
}
public class MyThread2 extends Thread{
private MyService service;
public MyThread2(MyService service) {
this.service = service;
}
@Override
public void run() {
for (int i=0; i<100; i++) {
service.get();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
MyThread1 a = new MyThread1(service);
a.start();
MyThread2 b = new MyThread2(service);
b.start();
}
}
---- **** ---- **** ---- **** ---- **** ...... |
---------------------------------------------------------------------------------------
2、实现生产者/消费者模式:多对多交替打印
public class MyService {
private ReentrantLock lock= new ReentrantLock();
private Condition condition = lock.newCondition();
private boolean hasValue = false;
public void set() {
try{
lock.lock();
while (hasValue == true) {
System.out.println("有可能--连续"); //就这里比上面的程序多了
condition.await();
}
System.out.println("----");
hasValue = true;
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
public void get() {
try {
lock.lock();
while (hasValue == false) {
System.out.println("有可能**连续"); //就这里比上面的程序多了
condition.await();
}
System.out.println("****");
hasValue = false;
condition.signal();
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
}
}
}
自定义线程同上
创建线程变多
public class Run {
public static void main(String[] args) throws InterruptedException {
MyService service = new MyService();
MyThread1[] threadA = new MyThread1[10];
MyThread2[] threadB = new MyThread2[10];
for (int i=0; i<10; i++) {
threadA[i] = new MyThread1(service);
threadB[i] = new MyThread2(service);
threadA[i].start();
threadB[i].start();
}
}
}
---- 有可能--连续 有可能--连续 **** 有可能**连续 有可能**连续 有可能**连续 有可能**连续 有可能**连续 ---- 有可能--连续 有可能--连续 有可能--连续 有可能--连续 有可能--连续 ...... |
根据第3章中的notifyAll()解决方案,可以使用signalAll()方法来解决。将MyService.java类中两处signal()代码改成signalAll()后,程序得到正确运行。
从控制台打印的日志可以发现,运行后不再出现假死状态,假死问题被解决了。
控制台中“----”和“****”是交替输出的,但是“有可能**连续”和“有可能--连续”却不是交替输出的,有时候出现连续打印的情况。原因是程序中使用了一个Condition对象,再结合signalAll()方法来唤醒所有的线程,那么唤醒的线程就有可能是同类,所以就出现连续打印“有可能**连续”或“有可能--连续”的情况了