java多线程生产消费打印输出倒顺序情况的原因

问题如下,一段简单的代码:

public class testPC2 {

public static void main(String[] args) {

TV tv=new TV();

new Publish(tv).start();

new Audience(tv).start();

}

}

class TV {

String name;

boolean flag = true;

public synchronized void play(String name) {

if(!flag){

try {

this.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

this.name=name;

this.flag=!this.flag;

this.notifyAll();

}

public synchronized String watch() {

if(flag){

try {

this.wait();

} catch (InterruptedException e) {

e.printStackTrace();

}

}

this.flag=!this.flag;

this.notifyAll();

return this.name;

}

}

class Publish extends Thread {

TV tv;

public Publish(TV tv) {

this.tv = tv;

}

@Override

public void run() {

String str;

for (int i = 0; i < 20; i++) {

if (i % 2 == 0) {

str = "快乐大本营";

} else {

str = "抖音:记录美好生活";

}

tv.play(str+(i+1));

System.out.println("生产了"+tv.name);

}

}

}

class Audience extends Thread {

TV tv;

public Audience(TV tv) {

this.tv = tv;

}

@Override

public void run() {

for (int i = 0; i < 20; i++) {

System.out.println("消费了-->"+tv.watch());

}

}

}

如下打印偶尔出现生产和消费倒序输出,消费方会抢线程?不知其中原因,望大佬告知。

生产了快乐大本营1
消费了-->快乐大本营1
消费了-->抖音:记录美好生活2
生产了抖音:记录美好生活2
生产了快乐大本营3
消费了-->快乐大本营3
消费了-->抖音:记录美好生活4
生产了抖音:记录美好生活4
生产了快乐大本营5
消费了-->快乐大本营5
生产了抖音:记录美好生活6
消费了-->抖音:记录美好生活6
消费了-->快乐大本营7
生产了快乐大本营7
生产了抖音:记录美好生活8
消费了-->抖音:记录美好生活8
生产了快乐大本营9
消费了-->快乐大本营9
生产了抖音:记录美好生活10
消费了-->抖音:记录美好生活10
生产了快乐大本营11
消费了-->快乐大本营11
生产了抖音:记录美好生活12
消费了-->抖音:记录美好生活12
生产了快乐大本营13
消费了-->快乐大本营13
消费了-->抖音:记录美好生活14
生产了抖音:记录美好生活14
生产了快乐大本营15
消费了-->快乐大本营15
生产了抖音:记录美好生活16
消费了-->抖音:记录美好生活16
生产了快乐大本营17
消费了-->快乐大本营17
消费了-->抖音:记录美好生活18
生产了抖音:记录美好生活18
生产了快乐大本营19
消费了-->快乐大本营19
生产了抖音:记录美好生活20
消费了-->抖音:记录美好生活20

问题找到,不是锁不锁公共资源的问题,实际上如果公共资源有缓存比如条件生产超过10个才wait(),那就得等它每生产完10个才能消费,显然不符合应用场景。实际上边生产边消费,才符合多线程的意义。
所以原代码没错,是System.out.println()这个方法没在方法锁里。应该把它放在notify之前。


回答:

在生产者与消费者 run里面加上synchronized,就可以得到你想要的结果,共享资源的读写访问需要同步

  synchronized(tv){

tv.play(str + (i + 1));

System.out.println( "生产了" + tv.name );

}

synchronized(tv){

System.out.println( "消费了-->" + tv.watch());

}

以上是 java多线程生产消费打印输出倒顺序情况的原因 的全部内容, 来源链接: utcz.com/p/944097.html

回到顶部