2013-05-16 5 views
4

Чтобы лучше понять Threading в Java, я написал следующий кодПочему потоковая обработка работает на одном ядре процессора?

public class SimpleRunnableTest { 
    public static void main(String[] args) throws InterruptedException { 
     long start = System.currentTimeMillis(); 

     Thread t1 = new Thread(new TT1()); 
     t1.start(); 
     Thread t2 = new Thread(new TT2()); 
     t2.start(); 

     t2.join(); 
     t1.join(); 

     long end = System.currentTimeMillis(); 
     System.out.println("end-start="+(end-start)); 
     } 
} 
class TT1 implements Runnable { 
    public void run(){ 
     try { 
      Thread.sleep(5000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
} 

class TT2 implements Runnable { 
    public void run() { 
     try { 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      e.printStackTrace(); 
     } 
    } 
}  

Идея заключается в том, если я бегу Thread.sleep(5000) и Thread.sleep(1000) последовательно в main тему, время, затрачиваемое будет 6 sec, но так как я использую Threading, это будет стоить только 5 sec на многоядерном процессоре, и это произошло. Но мой вопрос:

Почему результат все еще 5 sec на одноядерном процессоре? Конечно, используется Threading, но разве это не просто смоделированная резьба на мультиплексирование с временным разделением?

Мое понимание мультиплексирования с временным разделением: предположим, что Thread.sleep(5000) - задача A, а Thread.sleep(1000) - задача B, и мы могли бы разбить ее на части: A1, A2, A3; B1, B2

Последовательная просто: A1, A2, A3, B1, B2

Time Division Multiplexing Резьбонарезной просто: A1, B1, A2, B2, A3

Если да, то как же первый стоит 6 секунд, а второй - только 5?

Как я здесь основал базу?

+6

Один идет спать, возникает контекстный переключатель потока, затем другой выполняет (также собирается спать). –

+0

Реализация потоков зависит от конструктора системы, при одном его зеленом, в другом фиолетовом. Что вы предпочитаете? –

ответ

11

В результате получается 5, а не 6, поскольку два потока могут спать одновременно. Переключение на спящий режим при вызове Thread.sleep() позволяет запустить другой поток, но оставшийся таймер интервала ожидания продолжает тикать для обоих потоков.

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

+0

О, это хороший момент, я пойду проверю его – Will

+1

Просто протестирован, вы правы. Если задача - это реальная задача вместо сна, Threading не повлияет на общее время, затрачиваемое на «одноядерный не гиперпотоковый процессор», спасибо за помощь :) – Will

1

Вызывая Thread.sleep (sleeptime), Thread сообщает, что ему не нужен процессор, по крайней мере, для «sleeptime» millis.

Тем временем может быть выполнен другой поток.

+0

Но они не могут действительно спать 'в то же время ', правильно? На уровне процессора «то же время» достигается «мультиплексированием с временным разделением», что означает, что на самом деле происходит сон на некоторое время, а затем B, а затем A, а затем B ... потому что временной интервал настолько маленький для каждого потока, что создает иллюзию «спать в одно и то же время», разве это не то, как многопоточность достигается в первую очередь на одном ядре процессора? так как, во всяком случае, один процессор не может выполнять несколько команд за один раз, верно? – Will

+0

«sleep» здесь является синонимом «ничего не делать» - что должно было предотвратить два потока от двух потоков? Кроме того, текущие проекты ЦП с конвейерами и прогнозами делают много параллельно, даже на одном ядре – mschenk74