首页 新闻 会员 周边 捐助

关于多线程间通信的一个疑问

0
悬赏园豆:10 [已解决问题] 解决于 2018-09-14 14:28

阅读《Java多线程编程核心技术》线程间通信时遇到的一个问题,求解

package com.qf.test01;

import java.util.ArrayList;
import java.util.List;

/**

  • @author qf
  • @create 2018-09-13 17:47
    */
    public class MyList {
    private List list = new ArrayList();
    public void add(){
    list.add("qf");
    }
    public int size(){
    //System.out.println("MyList.size:"+list.size());
    return list.size();
    }
    }
    =============================
    package com.qf.test01;

/**

  • @author qf
  • @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;

/**

  • @author qf
  • @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;

/**

  • @author qf
  • @create 2018-09-14 9:23
    */
    public class Test {
    public static void main(String[] args) {
    MyList list = new MyList();
    ThreadA a = new ThreadA(list);
    a.setName("a");
    a.start();
    ThreadB b = new ThreadB(list);
    b.setName("b");
    b.start();
    }
    }
    ---------------------------------------------------------------------------------------------------------
    上面代码运行结果:
    a run
    添加了1个元素
    b run
    添加了2个元素
    添加了3个元素
    添加了4个元素
    添加了5个元素
    添加了6个元素
    添加了7个元素
    添加了8个元素
    添加了9个元素
    添加了10个元素

想问下,为什么b线程中设置抛异常的语句没有执行?

*青锋*的主页 *青锋* | 初学一级 | 园豆:180
提问于:2018-09-14 09:56
< >
分享
最佳答案
0

哇,这个问题我当时看这本书的时候,还特地去网上找了资料,现在有点忘记了,大致意思是说,线程b在执行过程中,它是很难准确的恰好满足myList.size() == 5这个条件的,或者你回觉得a每次将list加1的时候都会sleep一秒,按道理b应该在list.size=5的那一秒钟,应该会满足if判断的啊?我想这是因为b每次用的可能都是自己个工作内存中的缓存,所有才没有及时的反应出来。你可以看看这篇文章,也很有意思的:https://my.oschina.net/unteacher/blog/1793128

收获园豆:10
让我发会呆 | 老鸟四级 |园豆:2929 | 2018-09-14 10:41

嗯嗯,而且我发现在ThreadB.java的while块中加一个耗时的代码,也可以实现停止线程,但是不知道怎么解释原因
package com.qf.test01;

/**

  • @author qf
  • @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();
    }
    }
    }

*青锋* | 园豆:180 (初学一级) | 2018-09-14 10:46

@青锋: 我想是因为,这样线程b就会去主内存中去拉取最新的数据了,而不是只在自己的工作内存中拿数据。如果你了解java内存模型的话,应该很好理解了,但是这里面具体有没有什么硬件上的强制措施,我也就不太清楚了。比如你在while和if之间也sleep一秒,应该也是会抛出异常信息的。

让我发会呆 | 园豆:2929 (老鸟四级) | 2018-09-14 10:54

@让我发会呆: 嗯嗯,我觉得这个解释比较合理。这个想了一上午啦,谢谢您啦!

*青锋* | 园豆:180 (初学一级) | 2018-09-14 10:56
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册