2016-08-04 84 views
-1

嗨我想了解下面的代码的输出。根据我的理解,输出可能会不同的第一和第二个线程。但是当我执行下面的代码很多次,我仍然得到两个线程的值相同。无论我是错的还是正确的,都可以请一些人点亮。多线程程序的输出

package com.vikash.Threading; 

public class ThreadLocalExample { 

    public static class MyRunnable implements Runnable { 

     @SuppressWarnings("unused") 
     private ThreadLocal<Integer> threadLocal = new ThreadLocal<Integer>(); 
     D d=new D(); 

     @Override 
     public void run() { 
      //threadLocal.set((int) (Math.random() * 100D)); 
      d.setX((int) (Math.random() * 100D)); 
      //System.out.println(Thread.currentThread().getName()+" "+threadLocal.get()); 
      System.out.println(Thread.currentThread().getName()+" "+d.getX()); 
      try { 
       Thread.sleep(200); 
      } catch (InterruptedException e) { 
      } 
      //System.out.println(Thread.currentThread().getName()+" "+threadLocal.get()); 
      //System.out.println(Thread.currentThread().getName()+" "+d.getX()); 
     } 
    } 

    public static void main(String[] args) throws InterruptedException { 

     MyRunnable sharedRunnableInstance = new MyRunnable(); 

     Thread thread1 = new Thread(sharedRunnableInstance); 
     Thread thread2 = new Thread(sharedRunnableInstance); 

     thread1.start();thread1.setName("First"); 
     thread2.start();thread2.setName("Second");; 

     thread1.join(); //wait for thread 1 to terminate 
     thread2.join(); //wait for thread 2 to terminate 
    } 
} 
+0

@Vikash:代码缺乏同步的,这意味着,正式,结果未完全指定。换句话说,你不能保证结果会是什么。但是,您也没有任何保证,如果您多次运行它,*会看到不同的结果。可能发生的情况是,在特定的系统中,在特定的JVM版本,Java编译器等中,它可能会发生,您将始终看到相同的结果。但是,正式的说法(即根据JVM规范),你的代码不能保证有任何特定的结果。 –

+0

@Vikash:你可以通过多次运行“证明”自己的唯一一件事是:如果你看到不同的结果,你就有*缺乏同步的证据。但是,如果您运行多次并始终看到相同的结果,则您没有任何证据。测试同步问题真的很难! –

回答

1

这是因为你没有在d同步,所以会发生什么是线程1台X值,那么线程2套x值,则跟帖说已经由线程2同步块使复位1个打印值确保正确的值被印刷

synchronized (d) { 
    d.setX((int) (Math.random() * 100D)); 
    System.out.println(Thread.currentThread().getName() + " " + d.getX()); 
} 
+1

(该死的,在尝试添加更多文本时意外丢失了我的评论;重写它)在两个线程都启动之前,字段'd'被初始化,所以这里有一个发生前的关系。初始化后,没有什么会改变字段'd'。这意味着这两个线程都保证读取正确初始化的字段'd'。添加'volatile'不会改变任何东西:唯一可变的是建立发生 - 在写入到易失性字段的关系之后,读取相同的易失性字段。 –

+0

@BrunoReis你是对的,挥发性是不够的。相应地编辑我的答案。感谢您指出了这一点 – noscreenname