多线程消费者和生产者问题
一生产者一消费者问题:
- 多线程时候会发生假死,所有线程都要在wait状态,
- 因为生产者的 notify 有可能唤醒的是 生产者的wait,同理消费者的 notify 有可能唤醒的是消费者的 wait
- 此时 生产者没有被唤醒的程序 消费者也没有被唤醒的程序
代码:
package com.chapter03;
// 多线程时候会发生假死,所有线程都要在wait状态,
// 因为生产者的 notify 有可能唤醒的是 生产者的wait,同理消费者的 notify 有可能唤醒的是消费者的 wait
// 此时 生产者没有被唤醒的程序 消费者也没有被唤醒的程序
class ValueObject03 {
static String value = "";
}
class P03 {
private String lock;
public P03(String lock) {
this.lock = lock;
}
public void product() {
synchronized (lock) {
while (!ValueObject03.value.equals("")) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("生产");
ValueObject03.value = System.currentTimeMillis() + "";
lock.notify();
}
}
}
class C03 {
private String lock;
public C03(String lock) {
this.lock = lock;
}
public void custom() {
synchronized (lock) {
while (ValueObject03.value.equals("")) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("消费");
ValueObject03.value = "";
lock.notify();
}
}
}
class ThreadP extends Thread {
private P03 p03;
public ThreadP(P03 p03) {
this.p03 = p03;
}
@Override
public void run() {
while (true) {
p03.product();
}
}
}
class ThreadC extends Thread {
private C03 c03;
public ThreadC(C03 c03) {
this.c03 = c03;
}
@Override
public void run() {
while (true) {
c03.custom();
}
}
}
public class StudyThreads03一生产者一消费者 {
public static void main(String[] args) {
String lock = "anything";
P03 p03 = new P03(lock);
C03 c03 = new C03(lock);
ThreadP threadP = new ThreadP(p03);
ThreadC threadC = new ThreadC(c03);
threadP.start();
threadC.start();
}
}
多生产者多消费者:
注意: 判断条件为while,唤醒语句为notifyAll
package com.chapter03;
import java.util.ArrayList;
import java.util.List;
class MyStack {
private List list = new ArrayList();
synchronized public void product() {
while (list.size() == 5) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 睡眠随机时间
try {
Thread.sleep((long) Math.random() * 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
list.add(list.size());
System.out.println(Thread.currentThread().getName() + "生产者++++生产:" + list);
this.notify();
}
synchronized public void consumer() {
while (list.size() == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 睡眠随机时间
try {
Thread.sleep((long) Math.random() * 100);
} catch (InterruptedException e) {
e.printStackTrace();
}
list.remove(list.size() - 1);
System.out.println(Thread.currentThread().getName() + "消费者----消费:" + list);
this.notify();
}
}
class P04 extends Thread {
private MyStack myStack;
public P04(MyStack myStack) {
this.myStack = myStack;
}
@Override
public void run() {
while (true) {
myStack.product();
}
}
}
class C04 extends Thread {
private MyStack myStack;
public C04(MyStack myStack) {
this.myStack = myStack;
}
@Override
public void run() {
while (true) {
myStack.consumer();
}
}
}
public class StudyThreads04多生产者多消费者 {
public static void main(String[] args) {
MyStack myStack = new MyStack();
P04 p1 = new P04(myStack);
P04 p2 = new P04(myStack);
P04 p3 = new P04(myStack);
P04 p4 = new P04(myStack);
p1.setName("p1");
p2.setName("p2");
p3.setName("p3");
p4.setName("p4");
C04 c1 = new C04(myStack);
C04 c2 = new C04(myStack);
C04 c3 = new C04(myStack);
C04 c4 = new C04(myStack);
c1.setName("c1");
c2.setName("c2");
c3.setName("c3");
c4.setName("c4");
p1.start();
p2.start();
p3.start();
p4.start();
c1.start();
c2.start();
c3.start();
c4.start();
}
}