Java-在特定点上同步线程

Java-在特定点上同步线程,java,multithreading,Java,Multithreading,我需要在某个检查点同步一些线程,并且只有在所有线程都达到这一点之后,它们才应该继续。有什么简单的构造吗 for (int v = 0; v < 10; v++) { new Thread(new Runnable() { @Override public void run() { try { doFirst(); //checkpoint

我需要在某个检查点同步一些线程,并且只有在所有线程都达到这一点之后,它们才应该继续。有什么简单的构造吗

for (int v = 0; v < 10; v++) {
    new Thread(new Runnable() {
        @Override
        public void run() {
            try {

                doFirst();

                //checkpoint

                doSecond();

            } catch (Throwable e) {
                    e.printStackTrace();
            }
        }
    }).start();
}
for(int v=0;v<10;v++){
新线程(newrunnable()){
@凌驾
公开募捐{
试一试{
doFirst();
//检查站
doSecond();
}捕获(可丢弃的e){
e、 printStackTrace();
}
}
}).start();
}

您可以使用锁定对象执行此操作:

Integer threadCount = 10;

for (int i = 0; i < threadCount; i++)
{
    new Thread(() ->
    {
        try
        {
            doFirst();
            synchronized (threadCount)
            {
                threadCount--;
                while (threadCount > 0)
                    threadCount.wait();
                threadCount.notifyAll();
            }
            doSecond();
        }
        catch (Exception e) { e.printStackTrace(); }
    }).start();
}

// all threads are started, to wait until they've finished, call threadCount.wait();
Integer threadCount=10;
对于(int i=0;i
{
尝试
{
doFirst();
已同步(线程数)
{
线程数--;
而(线程数>0)
threadCount.wait();
threadCount.notifyAll();
}
doSecond();
}
catch(异常e){e.printStackTrace();}
}).start();
}
//所有线程都已启动,要等待它们完成,请调用threadCount.wait();
----或(少1行代码)----


如果您知道可以从java.util.concurrent使用的线程的确切数量

 // First initialize latch with your number of threads
 CountDownLatch latch = new CountDownLatch(N);

 // Then give this instance of latch to each of your threads

 // and finally at your checkpoint do
 latch.countDown();
 latch.await(); 

仅此而已。

一种方法是通过公共监视器同步线程:

Object monitor = new Object();
int jobCount = 0;

public void f1(){
 for (int v = 0; v < 10; v++) {
        new Thread(new Runnable() {
            @Override
            public void run() {
                try {

                doFirst();
                check();    

                doSecond();

                } catch (Throwable e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }
}

public void sleep(){}

public void check(){
    synchronized(monitor){
       jobCount++;
       if(jobCount==10){
           monitor.notifyAll();
           return;
       }
    }
    monitor.wait();
}
对象监视器=新对象();
int jobCount=0;
公共空间f1(){
对于(int v=0;v<10;v++){
新线程(newrunnable()){
@凌驾
公开募捐{
试一试{
doFirst();
检查();
doSecond();
}捕获(可丢弃的e){
e、 printStackTrace();
}
}
}).start();
}
}
public void sleep(){}
公共作废检查(){
同步(监视器){
jobCount++;
如果(作业计数==10){
monitor.notifyAll();
返回;
}
}
monitor.wait();
}
需要考虑的事项:

  • 当您调用monitor.wait()时,进行调用的线程将进入睡眠状态,并通过监视器进行同步
  • notifyAll()将唤醒所有正在睡眠和同步的线程。超过它的接收者
  • 当一个线程进入一个同步块时,它将锁定监视器。只有在收件人上存在锁时才能调用notifyAll()

  • 查看CyclicBarrier、CountDownLatch和deadlock。接下来,
    尝试{…}最后{latch.countDown();}
    是你的朋友。这就是java.util.concurrent.CountDownLatch所做的。@jameslarge不知道这样一个类的存在,但很高兴知道Oracle建议这样做:)似乎是最短的解决方案,我试试看
     // First initialize latch with your number of threads
     CountDownLatch latch = new CountDownLatch(N);
    
     // Then give this instance of latch to each of your threads
    
     // and finally at your checkpoint do
     latch.countDown();
     latch.await(); 
    
    Object monitor = new Object();
    int jobCount = 0;
    
    public void f1(){
     for (int v = 0; v < 10; v++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
    
                    doFirst();
                    check();    
    
                    doSecond();
    
                    } catch (Throwable e) {
                        e.printStackTrace();
                    }
                }
            }).start();
        }
    }
    
    public void sleep(){}
    
    public void check(){
        synchronized(monitor){
           jobCount++;
           if(jobCount==10){
               monitor.notifyAll();
               return;
           }
        }
        monitor.wait();
    }