阅读《Java多线程编程核心技术》线程间通信时遇到的一个问题,求解
package com.qf.test01;
import java.util.ArrayList;
import java.util.List;
/**
/**
@create 2018-09-13 17:45
*/
public class ThreadA extends Thread {
private MyList myList;
public ThreadA(MyList myList) {
this.myList = myList;
}
@Override
public void run() {
try {
System.out.println("a run");
for (int i = 0; i < 10; i++) {
myList.add();
System.out.println("添加了"+(i+1)+"个元素");
Thread.sleep(1000);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
=============================
package com.qf.test01;
/**
@create 2018-09-13 17:45
*/
public class ThreadB extends Thread {
private MyList myList;
public ThreadB(MyList myList) {
this.myList = myList;
}
@Override
public void run() {
try {
System.out.println("b run");
while (true){
if(myList.size() == 5){
System.out.println("线程b要退出了");
throw new InterruptedException();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
=============================
package com.qf.test01;
/**
想问下,为什么b线程中设置抛异常的语句没有执行?
哇,这个问题我当时看这本书的时候,还特地去网上找了资料,现在有点忘记了,大致意思是说,线程b在执行过程中,它是很难准确的恰好满足myList.size() == 5这个条件的,或者你回觉得a每次将list加1的时候都会sleep一秒,按道理b应该在list.size=5的那一秒钟,应该会满足if判断的啊?我想这是因为b每次用的可能都是自己个工作内存中的缓存,所有才没有及时的反应出来。你可以看看这篇文章,也很有意思的:https://my.oschina.net/unteacher/blog/1793128
嗯嗯,而且我发现在ThreadB.java的while块中加一个耗时的代码,也可以实现停止线程,但是不知道怎么解释原因
package com.qf.test01;
/**
@create 2018-09-13 17:45
*/
public class ThreadB extends Thread {
private MyList myList;
public ThreadB(MyList myList) {
this.myList = myList;
}
@Override
public void run() {
try {
System.out.println("b run");
while (true){
Object[] objects = new Object[1000000];//用来耗时
if(myList.size() == 5){
System.out.println("线程b要退出了");
throw new InterruptedException();
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@青锋: 我想是因为,这样线程b就会去主内存中去拉取最新的数据了,而不是只在自己的工作内存中拿数据。如果你了解java内存模型的话,应该很好理解了,但是这里面具体有没有什么硬件上的强制措施,我也就不太清楚了。比如你在while和if之间也sleep一秒,应该也是会抛出异常信息的。
@让我发会呆: 嗯嗯,我觉得这个解释比较合理。这个想了一上午啦,谢谢您啦!