java 多线程对象共享问题

新手上路,请多包涵

在java中,自定义了类MyList并且让其在两个线程中共享,一个线程往这个list中插入数据,另外一个线程在循环读这个list的size,当size达到一定个数之后就抛出异常。代码如下:


MyList 代码:

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

public class MyList {

    private List list = new ArrayList();

    public void add() {
        list.add("aaa");
    }

    public int size() {
        return list.size();
    }

}

ThreadA 代码:

public class ThreadA extends Thread {

    private volatile MyList list;

    public ThreadA(MyList myList) {
        super();
        list = myList;
    }

    public void run() {
        try {
            for (int i = 0; i < 10; i++) {
                list.add();
                System.out.println("add " + i + " element");
                Thread.sleep(1000);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

ThreadB 代码


public class ThreadB extends Thread {
    private  MyList list;

    public ThreadB(MyList myList) {
        list = myList;
    }

    public void run() {
        try {


            while (true) {

//                System.out.println("the size of list is ");
                if (list.size() >= 4) {
                    System.out.println("the size is 5 now");
                    throw new InterruptedException("the size is 4");
                }
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

测试代码:

public class TestAB {

    public static void main(String[] args) {
        MyList list = new MyList();

        ThreadA threadA = new ThreadA(list);
        threadA.setName("thread A");
        threadA.start();
        ThreadB threadB = new ThreadB(list);
        threadB.setName("thread B");
        threadB.start();
    }
}

在测试运行中,发现 ThreadB 会一直死循环。但是当将类中的那句打印语句放开或者断点运行,就会正常运行。这是什么原因呢?

阅读 3.2k
2 个回答

我的猜测是打印语句是进行IO操作的(必然),这里消耗的时间相对来说更多(IO操作速度和CPU的速度).断点操作就意味这运行很慢嘛,给了更多的IO操作的时间.应该可以解释为什么会正常运行的原因

java内存模型并不要求B看到A写的内容, B永远看到空列表也是正常的. 你说的"正常运行" 其实只是偶然.

如果要猜这个偶然的理由.. 可能是io的什么地方带了锁, 导致A中的写happens-before B中的读.

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题