public class ServiceResources {
private List<String> list = new ArrayList<>();
synchronized public void push() throws InterruptedException {
while (list.size() > 0) {
//說明有產品
System.out.println(Thread.currentThread().getName() + " 生產者進入睡眠");
this.wait();
}
System.out.println(Thread.currentThread().getName() + " 生產");
list.add("anything");
this.notify();
}
synchronized public void take() throws InterruptedException {
while (list.size() == 0) {
//說明此時沒有產品
System.out.println(Thread.currentThread().getName() + " 消費者進入睡眠");
this.wait();
}
System.out.println(Thread.currentThread().getName() + " 消費");
list.remove(0);
this.notify();
}
}
public class ThreadP extends Thread {
private ServiceResources resources;
public ThreadP(ServiceResources resources, String name) {
this.resources = resources;
this.setName(name);
}
@Override
public void run() {
while (true) {
try {
resources.push();
} catch (InterruptedException e) {
break;
}
}
}
}
public class ThreadC extends Thread {
private ServiceResources resources;
public ThreadC(ServiceResources resources, String name) {
this.resources = resources;
this.setName(name);
}
@Override
public void run() {
while (true) {
try {
resources.take();
} catch (InterruptedException e) {
break;
}
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
ServiceResources resources = new ServiceResources();
//建立多個生產者和多個消費者
ThreadP threadP1 = new ThreadP(resources, "P1");
ThreadP threadP2 = new ThreadP(resources, "P2");
ThreadC threadC1 = new ThreadC(resources, "C1");
ThreadC threadC2 = new ThreadC(resources, "C2");
threadP1.start();
threadP2.start();
threadC1.start();
threadC2.start();
Thread.sleep(5000);
threadP1.interrupt();
threadP2.interrupt();
threadC1.interrupt();
threadC2.interrupt();
//獲得所有執行緒的狀態
Thread[] threadArray = new Thread[Thread.currentThread().getThreadGroup().activeCount()];
Thread.currentThread().getThreadGroup().enumerate(threadArray);
for (int i = 0; i < threadArray.length; i++) {
System.out.println(threadArray[i].getName() + " " + threadArray[i].getState());
}
}
}
public class ServiceResources {
private List<String> list = new ArrayList<>();
synchronized public void push() throws InterruptedException {
if (list.size() > 0) {
//說明有產品
System.out.println(Thread.currentThread().getName() + " 生產者進入睡眠");
this.wait();
}
System.out.println(Thread.currentThread().getName() + " 生產");
list.add("anything");
this.notifyAll();
}
synchronized public void take() throws InterruptedException {
if (list.size() == 0) {
//說明此時沒有產品
System.out.println(Thread.currentThread().getName() + " 消費者進入睡眠");
this.wait();
}
System.out.println(Thread.currentThread().getName() + " 消費");
list.remove(0);
this.notifyAll();
}
}
public class Run {
public static void main(String[] args) throws InterruptedException {
ServiceResources resources = new ServiceResources();
//建立一個生產者和多個消費者
ThreadP threadP1 = new ThreadP(resources, "P1");
ThreadC threadC1 = new ThreadC(resources, "C1");
ThreadC threadC2 = new ThreadC(resources, "C2");
ThreadC threadC3 = new ThreadC(resources, "C3");
ThreadC threadC4 = new ThreadC(resources, "C4");
ThreadC threadC5 = new ThreadC(resources, "C5");
threadP1.start();
threadC1.start();
threadC2.start();
threadC3.start();
threadC4.start();
threadC5.start();
Thread.sleep(5000);
//獲得所有執行緒的狀態
Thread[] threadArray = new Thread[Thread.currentThread().getThreadGroup().activeCount()];
Thread.currentThread().getThreadGroup().enumerate(threadArray);
for (int i = 0; i < threadArray.length; i++) {
System.out.println(threadArray[i].getName() + " " + threadArray[i].getState());
}
}
}
比問題的出現就是因為在服務類中使用了if語句作為條件判斷,程式碼如下:
if (list.size() == 0) {
//說明此時沒有產品
System.out.println(Thread.currentThread().getName() + " 消費者進入睡眠");
this.wait();
}
因為條件發生改變時並沒有得到及時的響應,所以多個呈wait狀態的執行緒被喚醒,繼而執行list.remove(0)程式碼而出現異常。解決這個辦法是,將if改成while語句即可。