多线程不按预期工作

时间:2012-03-08 00:09:47

标签: java multithreading

我试图测试关于跨多个线程共享的迭代器的一些事情。我写了一个非常简单(而且非常愚蠢)的程序,它应该在不同的线程中迭代相同的映射。这是代码:

    final Map<Integer, Integer> m = new HashMap<Integer, Integer>();
    final Random r = new Random();
    for(int i = 0; i< 1000 ; i++){
        m.put(r.nextInt(10000), r.nextInt(10000));
    }
    Thread t1 = new Thread(new Runnable(){

        @Override
        public void run() {
            // TODO Auto-generated method stub
            Iterator<Integer> it = m.keySet().iterator();
            it.next();
            for(Integer i : m.keySet()){
                System.out.println("T1  " + i);
                try {
                    Thread.sleep(r.nextInt(100));
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    });

    Thread t2 = new Thread(new Runnable(){

        @Override
        public void run() {
            // TODO Auto-generated method stub
            Iterator<Integer> it = m.keySet().iterator();
            it.next();
            for(Integer i : m.keySet()){
                System.out.println("T2  " + i);
                try {
                    Thread.sleep(r.nextInt(100));
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }

    });

    t1.run();
    t2.run();

现在,当我运行这个时,我希望得到某种并发修改的异常,或者在控制台中混合使用“T1”和“T2”消息。会发生什么是我的程序从线程1的映射输出所有值,然后THEN进入线程2.为什么这种可序列化行为就是这里的情况?

2 个答案:

答案 0 :(得分:6)

您需要致电t1.start()t2.start()而不是run

致电run只会执行run方法中的代码 start是启动新线程的原因。

答案 1 :(得分:2)

您正在单个线程(主线程)中执行操作,因为您正在执行t.run()而不是t.start()。

话虽如此,请注意使用两个线程并不总是导致交错执行;通常按顺序执行操作更有效,因此JVM按顺序调度实际操作。

此外,标准哈希映射的并发修改检测是最好的努力,并不是一种保证机制。