麻烦老师帮忙看一下为什么不会被唤醒?
来源:5-1 线程间通信
qq_AnAvenue_0
2019-07-20 17:15:12
public class j41ThreadCommunication {
public static void main(String[] args){
Num num = new Num();
Producer p = new Producer(num);
Consumer c = new Consumer(num);
Thread ta = new Thread(p, "ta");
Thread tb = new Thread(c, "tb");
ta.start();
tb.start();
}
//wait()中断方法执行,使线程等待
//notify()唤醒处于等待的某一个线程,使其结束等待,
//notifyAll()唤醒所有处于等待的线程。
}
class Num{
private int a = 0;
boolean flag = false;
public void setA(int a){
this.a = a;
}
public int getA(){
return a;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
class Producer implements Runnable{
Num num;
public Producer(Num num){
this.num = num;
}
@Override
public synchronized void run(){
int i = 0;
while(i < 20){
System.out.println("s1"+num.isFlag());
if (num.isFlag()){
try {
System.out.println("1sg");
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int a = num.getA();
System.out.print("sa:"+a);
num.setA(++a);
i++;
System.out.println("生产"+i+"a:"+num.getA());
num.setFlag(true);
System.out.println("s2"+num.isFlag());
this.notifyAll();
System.out.println("激活消费");
}
}
}
class Consumer implements Runnable{
Num num;
public Consumer(Num num){
this.num = num;
}
@Override
public synchronized void run(){
int i = 0;
while(i < 20){
System.out.println("x1"+num.isFlag());
if(!num.isFlag()){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
int a = num.getA();
System.out.print("xa:"+a);
num.setA(--a);
i++;
System.out.println("消费"+i+"a:"+num.getA());
num.setFlag(false);
System.out.println("x2"+num.isFlag());
this.notifyAll();
System.out.println("激活生产");
}
}
}5回答
吃吃吃鱼的猫
2019-07-21
同学你好,同学新贴出来的代码运行后没有问题哦~
原因是:在每个线程执行过程中,对num加锁。
相当于两个资源访问num,加锁后,不会出现冲突,所以是正确的哦~
如果我的回答解决了你的疑惑,请采纳。祝:学习愉快~
qq_AnAvenue_0
提问者
2019-07-21
public class j41ThreadCommunication {
public static void main(String[] args){
Num num = new Num();
Producer p = new Producer(num);
Consumer c = new Consumer(num);
Thread ta = new Thread(p, "ta");
Thread tb = new Thread(c, "tb");
ta.start();
tb.start();
}
}
class Num{
private int a = 0;
boolean flag = false;
public void setA(int a){
this.a = a;
}
public int getA(){
return a;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
class Producer implements Runnable{
Num num;
public Producer(Num num){
this.num = num;
}
@Override
public void run(){
int i = 0;
while(i < 20){
System.out.println("s1"+num.isFlag());
if (num.isFlag()){
synchronized (num){
try {
System.out.println("1sg");
num.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
int a = num.getA();
System.out.print("sa:"+a);
num.setA(++a);
i++;
System.out.println("生产"+i+"a:"+num.getA());
num.setFlag(true);
//System.out.println("s2"+num.isFlag());
synchronized (num){
num.notifyAll();
}
System.out.println("激活消费");
}
}
}
class Consumer implements Runnable{
Num num;
public Consumer(Num num){
this.num = num;
}
@Override
public void run(){
int i = 0;
while(i < 20){
System.out.println("x1"+num.isFlag());
if(!num.isFlag()){
synchronized (num){
try {
num.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
int a = num.getA();
System.out.print("xa:"+a);
num.setA(--a);
i++;
System.out.println("消费"+i+"a:"+num.getA());
num.setFlag(false);
//System.out.println("x2"+num.isFlag());
synchronized (num){
num.notifyAll();
}
System.out.println("激活生产");
}
}
}该代码可得到正确结果
吃吃吃鱼的猫
2019-07-21
同学你好,建议同学贴出相关的完整代码,方便老师为同学解答问题~
如果我的回答解决了你的疑惑,请采纳。祝:学习愉快~
吃吃吃鱼的猫
2019-07-21
同学你好,
在一个线程的run方法中,是不能直接调用此线程的notifyAll唤醒所有线程的方法的。
如果我的回答解决了你的疑惑,请采纳。祝:学习愉快~
好帮手慕阿莹
2019-07-20
同学你好,同学不应该在生产者和消费着中进行wait(),而是在Num中wait()并唤醒。
在生产者和消费着中,应只是去调用他们的Num对象的set和get方法,
应该把synchronized加在 Num中的set和get方法上。无论是生产还是消费,都应该在Num去做,而Producer和Consumer 只是模拟调用方法。是否可以去生产还是消费,应该由Num去把控。
所以,老师对同学的代码做了如下修改。
public class j41ThreadCommunication {
public static void main(String[] args){
Num num = new Num();
Producer p = new Producer(num);
Consumer c = new Consumer(num);
Thread ta = new Thread(p, "ta");
Thread tb = new Thread(c, "tb");
ta.start();
tb.start();
}
//wait()中断方法执行,使线程等待
//notify()唤醒处于等待的某一个线程,使其结束等待,
//notifyAll()唤醒所有处于等待的线程。
}
class Num{
private int a = 0;
boolean flag = false;
public synchronized void setA(int a){
if(flag) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
this.a=a;
System.out.println("生成a的值"+a);
this.flag = true;
this.notifyAll();
}
public synchronized int getA(){
if(!flag) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println("消费a的值"+a);
flag =false;
this.notifyAll();
return a;
}
}
class Producer implements Runnable{
Num num;
public Producer(Num num){
this.num = num;
}
@Override
public void run(){
int i =0;
while (true) {
num.setA(i);
i++;
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
class Consumer implements Runnable{
Num num;
public Consumer(Num num){
this.num = num;
}
@Override
public void run(){
while (true) {
System.out.println(num.getA());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}建议同学可以再回顾一下本节课程 呦。
如果我的回答解决了你的疑惑,请采纳!祝学习愉快!
相似问题
回答 4
回答 1