Below is the code concerning Thread running a producer and a consumer.
public class PC1 {
public static final int limit = 3;
public static void main(String[] args) {
List bag = new ArrayList();
Producer p = new Producer(bag);
Consumer c = new Consumer(bag);
Thread t1 = new Thread(p, "t1");
Thread t2 = new Thread(c, "t2");
Thread t3 = new Thread(p, "t3");
Thread t4 = new Thread(c, "t4");
Thread t5 = new Thread(p, "t5");
Thread t6 = new Thread(c, "t6");
t2.start();
t4.start();
t6.start();
t1.start();
t3.start();
t5.start();
}
}
class Producer implements Runnable {
private List bag;
public Producer(List bag) {
this.bag = bag;
}
@Override
public void run() {
synchronized (bag) {
while (true) {
while (bag.size() >= PC1.limit) {
bag.notify();
System.out.println(Thread.currentThread().getName() + "@@@@@@@@@@@");
try {
bag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int curr = bag.size();
bag.add(++curr);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " produce " + curr);
}
}
}
}
class Consumer implements Runnable {
private List bag;
public Consumer(List bag) {
this.bag = bag;
}
@Override
public void run() {
synchronized (bag) {
while (true) {
while (bag.size() <= 0) {
bag.notify();
System.out.println(Thread.currentThread().getName() + "!!!!!!!!!!!");
try {
bag.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int curr = bag.size();
bag.remove(curr - 1);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " consume " + (bag.size() + 1));
}
}
}
}
t2!!!!!!!!!!!
t3 produce 1
t3 produce 2
t3 produce 3
t3@@@@@@@@@@@
t1@@@@@@@@@@@
t6 consume 3
t6 consume 2
t6 consume 1
t6!!!!!!!!!!!
t4!!!!!!!!!!!
t6!!!!!!!!!!!
t4!!!!!!!!!!!
t6!!!!!!!!!!!
t4!!!!!!!!!!!
t6!!!!!!!!!!!
t4!!!!!!!!!!!
t6!!!!!!!!!!!
t4!!!!!!!!!!!
t6!!!!!!!!!!!
t4!!!!!!!!!!!
t6!!!!!!!!!!!
t4!!!!!!!!!!!
t6!!!!!!!!!!!
t4!!!!!!!!!!!
t6!!!!!!!!!!!
t4!!!!!!!!!!!
.
.
....like this all the time t6 and t4 alternate
above is the result on my console.As you can see:t2,t3,t1 obtain chance to excute at the beginning,then t6 and t4 alternate,other threads would never get chance to excute.
let me interpret its process.
First,t2 gets privilege to consume,bag.size=0,wait
then,t3 gets privilege to produce,after 3 times,bag is full,notify t2 to make it enter competing state,self wait
then,t1 gets privilege to product,as bag is full,notify t3 to make it enter competing state,self wait
then,t6 gets privilege to consume,after 3 times,bag is empty,notify t3 to make it enter competing state,self wait
then,t4 gets privilege to consume,as bag is empty,notify t6 to make it enter competing state,self wait
.
.
.
I m confused about before t4 wait,all other 5 thread are in competing state,however,the result shows only t4 and t6 alternate,other threads would never get chance to excute.Why that happens?
And another question is that if I modify notify to notifyAll,all 6 threads do get chance to excute.In my understanding,if multi threads are all in competing state,they all should have chance to excute.