Pan*_*edi 1 java multithreading synchronization
我有以下方法,由大约100多个线程运行.
<Method Signature>
{
System.out.println("Starting Thread with ID :- " + iThreadID);
<Some piece of code which takes more than 10 seconds to complete>
System.out.println("Finished Thread with ID :- " + iThreadID);
}
Run Code Online (Sandbox Code Playgroud)
当线程执行时,我得到以下输出.
Starting Thread with ID :- 1
Starting Thread with ID :- 6
Starting Thread with ID :- 14
Starting Thread with ID :- 9
Starting Thread with ID :- 69
Starting Thread with ID :- 21
Starting Thread with ID :- 87
Starting Thread with ID :- 13
Starting Thread with ID :- 10
Starting Thread with ID :- 45
**Finished Thread with ID :- 1**
Starting Thread with ID :- 30
Starting Thread with ID :- 25
Starting Thread with ID :- 32
**Finished Thread with ID :- 87**
...
Run Code Online (Sandbox Code Playgroud)
并非所有100个线程都一起启动.某些线程在创建其他线程之前完成其方法执行.
为什么会这样?有什么我可以做的,以确保所有线程都是在很长的时间之前创建的,执行代码的时间是多少?
来自评论:
我想要的是所有线程必须先执行一组代码才能在其中任何一个代码执行该代码之后执行代码.
用一个CountDownLatch.javadoc准确描述了您的需求:
允许一个或多个线程等待直到在其他线程中执行的一组操作完成的同步辅助.
如果您想多次执行此操作,请使用CyclicBarrier:
一种同步辅助工具,允许一组线程全部等待彼此到达公共障碍点.CyclicBarriers在涉及固定大小的线程方的程序中很有用,这些线程必须偶尔等待彼此.屏障称为循环,因为它可以在等待线程释放后重新使用.
这是代码显示两者.
测试辅助方法
private static void test(int count, Supplier<Thread> threadProducer) {
Thread[] threads = new Thread[count];
for (int i = 0; i < count; i++) {
threads[i] = threadProducer.get();
threads[i].start();
}
System.out.println("Ready");
for (int i = 0; i < count; i++)
try {
threads[i].join();
} catch (InterruptedException e) {
System.out.println(threads[i].getName() + ": " + e);
}
System.out.println("All Done");
}
Run Code Online (Sandbox Code Playgroud)
CountDownLatch
class LatchThread extends Thread {
private final CountDownLatch countDownLatch;
public LatchThread(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
try {
System.out.println(getName() + ": Started");
this.countDownLatch.countDown();
this.countDownLatch.await();
System.out.println(getName() + ": Done");
} catch (InterruptedException e) {
System.out.println(getName() + ": " + e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出显示线程等到所有线程都已启动,即直到所有线程都已调用countDown().
CountDownLatch countDownLatch = new CountDownLatch(10);
test(10, () -> new LatchThread(countDownLatch));
Run Code Online (Sandbox Code Playgroud)
Thread-0: Started
Thread-4: Started
Thread-5: Started
Thread-3: Started
Thread-2: Started
Thread-1: Started
Thread-8: Started
Thread-9: Started
Thread-6: Started
Thread-7: Started
Ready
Thread-7: Done
Thread-4: Done
Thread-2: Done
Thread-0: Done
Thread-6: Done
Thread-8: Done
Thread-1: Done
Thread-9: Done
Thread-3: Done
Thread-5: Done
All Done
Run Code Online (Sandbox Code Playgroud)
CyclicBarrier
class BarrierThread extends Thread {
private final CyclicBarrier cyclicBarrier;
public BarrierThread(CyclicBarrier cyclicBarrier) {
this.cyclicBarrier = cyclicBarrier;
}
@Override
public void run() {
try {
System.out.println(getName() + ": Started");
if (this.cyclicBarrier != null) this.cyclicBarrier.await();
System.out.println(getName() + ": Phase 1");
if (this.cyclicBarrier != null) this.cyclicBarrier.await();
System.out.println(getName() + ": Phase 2");
if (this.cyclicBarrier != null) this.cyclicBarrier.await();
System.out.println(getName() + ": Done");
} catch (InterruptedException | BrokenBarrierException e) {
System.out.println(getName() + ": " + e);
}
}
}
Run Code Online (Sandbox Code Playgroud)
输出显示线程在进入下一阶段之前等待彼此.
CyclicBarrier cyclicBarrier = new CyclicBarrier(10);
test(10, () -> new BarrierThread(cyclicBarrier));
Run Code Online (Sandbox Code Playgroud)
Thread-0: Started
Thread-5: Started
Thread-4: Started
Thread-2: Started
Thread-6: Started
Thread-1: Started
Thread-3: Started
Thread-7: Started
Thread-9: Started
Thread-8: Started
Ready
Thread-8: Phase 1
Thread-5: Phase 1
Thread-4: Phase 1
Thread-6: Phase 1
Thread-0: Phase 1
Thread-9: Phase 1
Thread-7: Phase 1
Thread-3: Phase 1
Thread-1: Phase 1
Thread-2: Phase 1
Thread-2: Phase 2
Thread-8: Phase 2
Thread-6: Phase 2
Thread-7: Phase 2
Thread-1: Phase 2
Thread-4: Phase 2
Thread-5: Phase 2
Thread-3: Phase 2
Thread-9: Phase 2
Thread-0: Phase 2
Thread-0: Done
Thread-8: Done
Thread-4: Done
Thread-2: Done
Thread-9: Done
Thread-3: Done
Thread-5: Done
Thread-1: Done
Thread-6: Done
Thread-7: Done
All Done
Run Code Online (Sandbox Code Playgroud)
相比之下,没有障碍,输出显示线程不会彼此等待.
test(10, () -> new BarrierThread(null));
Run Code Online (Sandbox Code Playgroud)
Thread-0: Started
Ready
Thread-4: Started
Thread-4: Phase 1
Thread-4: Phase 2
Thread-4: Done
Thread-1: Started
Thread-1: Phase 1
Thread-1: Phase 2
Thread-1: Done
Thread-5: Started
Thread-5: Phase 1
Thread-5: Phase 2
Thread-5: Done
Thread-2: Started
Thread-2: Phase 1
Thread-2: Phase 2
Thread-2: Done
Thread-3: Started
Thread-6: Started
Thread-6: Phase 1
Thread-7: Started
Thread-9: Started
Thread-9: Phase 1
Thread-8: Started
Thread-8: Phase 1
Thread-8: Phase 2
Thread-8: Done
Thread-0: Phase 1
Thread-0: Phase 2
Thread-0: Done
Thread-9: Phase 2
Thread-9: Done
Thread-7: Phase 1
Thread-7: Phase 2
Thread-7: Done
Thread-6: Phase 2
Thread-3: Phase 1
Thread-3: Phase 2
Thread-3: Done
Thread-6: Done
All Done
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
117 次 |
| 最近记录: |