1.一生产与一消费:操作值
* 屁话没有,直接看例子
public class P {
private String lock;
public P(String lock){
super();
this.lock=lock;
}
public void setValue(){
try{
synchronized (lock){
if(!ValueObject.value.equals("")){
lock.wait();
}
String value=System.currentTimeMillis()+"_"+System.nanoTime();
System.out.println("set 的值是"+value);
ValueObject.value=value;
lock.notify();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public class C {
private String lock;
public C(String lock){
super();
this.lock=lock;
}
public void getValue(){
try{
synchronized (lock){
if(ValueObject.value.equals("")){
lock.wait();
}
System.out.println("get的值是"+ValueObject.value);
ValueObject.value="";
lock.notify();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public class ValueObject {
public static String value="";
}
public class ThreadP extends Thread{
private P p;
public ThreadP(P p){
super();
this.p=p;
}
@Override
public void run() {
while (true){
p.setValue();
}
}
}
public class ThreadC extends Thread{
private C r;
public ThreadC(C r){
super();
this.r=r;
}
@Override
public void run() {
while(true){
r.getValue();
}
}
}
public class Run {
public static void main(String[] args){
String lock=new String("");
P p=new P(lock);
C r=new C(lock);
ThreadP threadP=new ThreadP(p);
ThreadC threadC=new ThreadC(r);
threadP.start();
threadC.start();
}
}
交替执行,很完美
2. 多生产与多消费:操作值-假死
* 先看例子,找到问题
public class C {
private String lock;
public C(String lock){
super();
this.lock=lock;
}
public void getValue(){
try{
synchronized (lock){
while (ValueObject.value.equals("")){
System.out.println("消费者 "+Thread.currentThread().getName()+" WAITING了*");
lock.wait();
}
System.out.println("消费者 "+Thread.currentThread().getName()+" RUNNABLE了");
ValueObject.value="";
lock.notify();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public class P {
private String lock;
public P(String lock) {
super();
this.lock = lock;
}
public void setValue() {
try {
synchronized (lock) {
while (!ValueObject.value.equals("")) {
System.out.println("生产者" + Thread.currentThread().getName() + " WAITINGl *");
lock.wait();
}
System.out.println("生产者 " + Thread.currentThread().getName() + " RUNNABLE了");
String value = System.currentTimeMillis() + "_" + System.nanoTime();
ValueObject.value = value;
lock.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadC extends Thread {
private C c;
public ThreadC(C r){
super();
this.c=r;
}
@Override
public void run() {
while(true){
c.getValue();
}
}
}
public class ThreadP extends Thread{
private P p;
public ThreadP(P p){
super();
this.p=p;
}
@Override
public void run() {
while(true){
p.setValue();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException{
String lock=new String("");
P p=new P(lock);
C r=new C(lock);
ThreadP[] threadP=new ThreadP[2];
ThreadC[] threadC=new ThreadC[2];
for(int i=0;i<2;i++){
threadP[i]=new ThreadP(p);
threadP[i].setName("生产者 "+(i+1));
threadC[i]=new ThreadC(r);
threadC[i].setName("消费者 "+(i+1));
threadP[i].start();
threadC[i].start();
}
Thread.sleep(5000);
Thread[] threads=new Thread[Thread.currentThread().getThreadGroup().activeCount()];
Thread.currentThread().getThreadGroup().enumerate(threads);
for(int i=0;i<threads.length;i++){
System.out.println(threads[i].getName()+" "+threads[i].getState());
}
}
}
效果:
.....
消费者 消费者 2 WAITING了*
消费者 消费者 1 WAITING了*
main RUNNABLE
Monitor Ctrl-Break RUNNABLE
生产者 1 WAITING
消费者 1 WAITING
生产者 2 WAITING
消费者 2 WAITING
* 分析:notify()是随机唤醒的,他并不知道谁是生产者谁是消费者,仅仅去唤醒一个wait的线程
考虑这样一种情况:value中有数据,两个生产者都处于等待状态,然后执行了一个消费者线程,
线程中有数据了,唤醒一个线程,该线程为其中一个生产者,该生产者检测没有数据,生产一个数据,
然后唤醒一个线程,因为另外一个线程处于等待状态,所以刚好唤醒了该线程,如此,消费者就不能得到执行了,
就会陷入相互等待。
*解决办法:把notify()改成notifyAll()。
* 屁话没有,直接看例子
public class P {
private String lock;
public P(String lock){
super();
this.lock=lock;
}
public void setValue(){
try{
synchronized (lock){
if(!ValueObject.value.equals("")){
lock.wait();
}
String value=System.currentTimeMillis()+"_"+System.nanoTime();
System.out.println("set 的值是"+value);
ValueObject.value=value;
lock.notify();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public class C {
private String lock;
public C(String lock){
super();
this.lock=lock;
}
public void getValue(){
try{
synchronized (lock){
if(ValueObject.value.equals("")){
lock.wait();
}
System.out.println("get的值是"+ValueObject.value);
ValueObject.value="";
lock.notify();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public class ValueObject {
public static String value="";
}
public class ThreadP extends Thread{
private P p;
public ThreadP(P p){
super();
this.p=p;
}
@Override
public void run() {
while (true){
p.setValue();
}
}
}
public class ThreadC extends Thread{
private C r;
public ThreadC(C r){
super();
this.r=r;
}
@Override
public void run() {
while(true){
r.getValue();
}
}
}
public class Run {
public static void main(String[] args){
String lock=new String("");
P p=new P(lock);
C r=new C(lock);
ThreadP threadP=new ThreadP(p);
ThreadC threadC=new ThreadC(r);
threadP.start();
threadC.start();
}
}
交替执行,很完美
2. 多生产与多消费:操作值-假死
* 先看例子,找到问题
public class C {
private String lock;
public C(String lock){
super();
this.lock=lock;
}
public void getValue(){
try{
synchronized (lock){
while (ValueObject.value.equals("")){
System.out.println("消费者 "+Thread.currentThread().getName()+" WAITING了*");
lock.wait();
}
System.out.println("消费者 "+Thread.currentThread().getName()+" RUNNABLE了");
ValueObject.value="";
lock.notify();
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public class P {
private String lock;
public P(String lock) {
super();
this.lock = lock;
}
public void setValue() {
try {
synchronized (lock) {
while (!ValueObject.value.equals("")) {
System.out.println("生产者" + Thread.currentThread().getName() + " WAITINGl *");
lock.wait();
}
System.out.println("生产者 " + Thread.currentThread().getName() + " RUNNABLE了");
String value = System.currentTimeMillis() + "_" + System.nanoTime();
ValueObject.value = value;
lock.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class ThreadC extends Thread {
private C c;
public ThreadC(C r){
super();
this.c=r;
}
@Override
public void run() {
while(true){
c.getValue();
}
}
}
public class ThreadP extends Thread{
private P p;
public ThreadP(P p){
super();
this.p=p;
}
@Override
public void run() {
while(true){
p.setValue();
}
}
}
public class Run {
public static void main(String[] args) throws InterruptedException{
String lock=new String("");
P p=new P(lock);
C r=new C(lock);
ThreadP[] threadP=new ThreadP[2];
ThreadC[] threadC=new ThreadC[2];
for(int i=0;i<2;i++){
threadP[i]=new ThreadP(p);
threadP[i].setName("生产者 "+(i+1));
threadC[i]=new ThreadC(r);
threadC[i].setName("消费者 "+(i+1));
threadP[i].start();
threadC[i].start();
}
Thread.sleep(5000);
Thread[] threads=new Thread[Thread.currentThread().getThreadGroup().activeCount()];
Thread.currentThread().getThreadGroup().enumerate(threads);
for(int i=0;i<threads.length;i++){
System.out.println(threads[i].getName()+" "+threads[i].getState());
}
}
}
效果:
.....
消费者 消费者 2 WAITING了*
消费者 消费者 1 WAITING了*
main RUNNABLE
Monitor Ctrl-Break RUNNABLE
生产者 1 WAITING
消费者 1 WAITING
生产者 2 WAITING
消费者 2 WAITING
* 分析:notify()是随机唤醒的,他并不知道谁是生产者谁是消费者,仅仅去唤醒一个wait的线程
考虑这样一种情况:value中有数据,两个生产者都处于等待状态,然后执行了一个消费者线程,
线程中有数据了,唤醒一个线程,该线程为其中一个生产者,该生产者检测没有数据,生产一个数据,
然后唤醒一个线程,因为另外一个线程处于等待状态,所以刚好唤醒了该线程,如此,消费者就不能得到执行了,
就会陷入相互等待。
*解决办法:把notify()改成notifyAll()。