2015-05-27 3 views
2

В Эффективной Java Joshua Bloch, пункт 66, он иллюстрирует неудачу в жизни, не передавая переменную между потоками.Как проверить неудачи жизнедеятельности?

// Broken! - How long would you expect this program to run? 
public class StopThread { 
    private static boolean stopRequested; 
     public static void main(String[] args) throws InterruptedException { 
     Thread backgroundThread = new Thread(new Runnable() { 
      public void run() { 
       int i = 0; 
       while (!stopRequested) 
        i++; 
      } 
     }); 
     backgroundThread.start(); 
     TimeUnit.SECONDS.sleep(1); 
     stopRequested = true; 
    } 
} 

Он говорит, что на его собственной машине это никогда не заканчивается и дает две причины. Я попробовал это на своей собственной машине, на Oracle JDK 7u75 (новейшие 7), и она ВСЕГДА заканчивается через одну секунду. Я также попытался запустить runtime с -XX:+AggressiveOpts без успеха. Есть ли причина, по которой это не работает по назначению (изменить: i.e. не зацикливание навсегда)? Является ли Джошуа другим временем выполнения? У меня четырехъядерный мост плюща.

ответ

1

stopRequested не volatile. Таким образом, нет никакой гарантии, что изменения, внесенные в нее основным потоком, будут видны backgroundThread. Изменения могут быть замечены, изменения могут быть не видны. Нет никакой гарантии. Итак, (как всегда), Джошуа прав :)

+0

Не может быть никакой гарантии, но я, по крайней мере, ожидаю, что он потерпит неудачу, потому что два потока на четырехъядерном процессоре должны использовать разные ядра (кэш L1 и L2 оба в ядре) –

+0

@MarkJeronimus - :) 4 физических ядра = 8 логических ядер (HyperThreading). Итак, в идеале да, 2 потока должны использовать разные ядра. Но каждый поток будет считывать данные из собственного кеша. Таким образом, основной поток будет завершен, пока фоновый поток ждет навсегда. Почему вы ожидаете, что булевское значение будет записано одним потоком, чтобы его можно было увидеть другим? – TheLostMind

+0

Я ожидаю, что этого не будет. («Работа по назначению» означает сбой, потому что отсутствует «volatile»). Но это. И действительно, я заметил, что у меня гиперпоточность, и это может быть причиной. –