2016-08-04 2 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 комплекта х значение, то нить 1 печатает значение, которое уже переназначен нить 2. Synchronize блока составляет убедитесь, что правильное значение напечатано

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

(черт возьми, потерял мой комментарий случайно, пытаясь добавить больше текста, переписав его) Поле 'd' инициализируется до начала обоих потоков, так что здесь происходит связь между ними. Ничто никогда не изменяет поле 'd' после этой инициализации. Это означает, что обе нити гарантированно корректно инициализируют поле 'd'. Добавление 'volatile' ничего не меняет: единственная вещь, которую volatile делает, устанавливается - до отношений записи в поле volatile, за которым следуют прочтения одного и того же изменчивого поля. –

+0

@BrunoReis вы правы, неустойчивого здесь недостаточно. Соответственно отредактировал мой ответ. Спасибо за указание на это – noscreenname

Смежные вопросы