Потоки повинні починатися з тієї ж частки секунди. Я розумію, якщо ви це зробите thread1.start()
, це займе кілька мілісекунд перед наступним виконанням thread2.start()
.
Це взагалі можливо чи неможливо?
Потоки повинні починатися з тієї ж частки секунди. Я розумію, якщо ви це зробите thread1.start()
, це займе кілька мілісекунд перед наступним виконанням thread2.start()
.
Це взагалі можливо чи неможливо?
Відповіді:
Щоб запустити потоки точно в той самий час (принаймні наскільки це можливо), ви можете використовувати CyclicBarrier :
// We want to start just 2 threads at the same time, but let's control that
// timing from the main thread. That's why we have 3 "parties" instead of 2.
final CyclicBarrier gate = new CyclicBarrier(3);
Thread t1 = new Thread(){
public void run(){
gate.await();
//do stuff
}};
Thread t2 = new Thread(){
public void run(){
gate.await();
//do stuff
}};
t1.start();
t2.start();
// At this point, t1 and t2 are blocking on the gate.
// Since we gave "3" as the argument, gate is not opened yet.
// Now if we block on the gate from the main thread, it will open
// and all threads will start to do stuff!
gate.await();
System.out.println("all threads started");
Це не повинно бути a CyclicBarrier
, ви також можете використовувати a CountDownLatch
або навіть замок.
Це все ще не може переконатись, що вони запускаються точно одночасно на стандартних JVM, але ви можете наблизитись досить близько. Приблизитися все ще корисно, коли ви проводите, наприклад, тести продуктивності. Наприклад, якщо ви намагаєтеся виміряти пропускну здатність структури даних з різною кількістю потоків, що потрапляють на неї, ви хочете використовувати цей тип конструкції, щоб отримати максимально точний результат.
На інших платформах, починаючи потоки точно можуть бути дуже дійсне вимога до речі.
CreateEvent
. msdn.microsoft.com/en-us/library/ms686364%28VS.85%29.aspx
Це неможливо, принаймні на одноядерному комп'ютері. Але чому ти цього хочеш? Навіть якщо ви змогли запустити два потоки точно в одну секунду, вони будуть прогресувати по-різному, оскільки планування не залежить від вашого контролю.
Редагувати: (у відповідь на деякі коментарі) Це цілком обґрунтована вимога до синхронізації стану чи прогресу декількох потоків і CyclicBarrier
є чудовим інструментом. Я відповів на питання, чи можна запустити кілька потоків одночасно . CyclicBarrier
гарантуватиме, що нитки продовжуватимуться, коли вони будуть точно в бажаному стані, але це не гарантує, що вони почнуться або відновляться точно в той же час, хоча це може бути досить близько. У запитанні немає згадки про потреби синхронізації.
Для цього ви можете використовувати CountDownLatch. Нижче наведено зразок. Хоча t1 і t2 запущені, ці потоки продовжують чекати, поки основний потік не відлічить фіксатор. Кількість необхідних зворотних відліків згадується в конструкторі. Засувку зворотного відліку можна також використовувати для очікування завершення потоків, щоб основний потік міг продовжувати далі (зворотний випадок). Цей клас був включений з Java 1.5.
import java.util.concurrent.CountDownLatch;
public class ThreadExample
{
public static void main(String[] args)
{
CountDownLatch latch = new CountDownLatch(1);
MyThread t1 = new MyThread(latch);
MyThread t2 = new MyThread(latch);
new Thread(t1).start();
new Thread(t2).start();
//Do whatever you want
latch.countDown(); //This will inform all the threads to start
//Continue to do whatever
}
}
class MyThread implements Runnable
{
CountDownLatch latch;
public MyThread(CountDownLatch latch)
{
this.latch = latch;
}
@Override
public void run()
{
try
{
latch.await(); //The thread keeps waiting till it is informed
} catch (InterruptedException e) {
e.printStackTrace();
}
//Do the actual thing
}
}