0

如何使用CounDownLatch两个不同的线程,每个线程都有相同的可运行类?我希望 FICS 和 fiCS_R7 具有相同的可运行类 FICS,但是当 fiCS_R3 完成时 fiCS_R7 启动。

我怎样才能做到这一点。

代码

    public FICSFilter(Mat bgrMat, int csRadius) {
        // TODO Auto-generated constructor stub
        this.bgrMat = bgrMat;
        this.csRadius = csRadius;

        CountDownLatch latch = new CountDownLatch(1);

        this.fiCS_R3 = new Thread(new FICS(this.bgrMat, 3), "FICS_R" + this.csRadius);
        fiCS_R3.start();

        this.fiCS_R3 = new Thread(new FICS(this.bgrMat, 7), "FICS_R" + this.csRadius);
        fiCS_R7.start();

        //How to use the CounDownLatch for two different threads each of them has the same runnable class
        }

    private class FICS implements Runnable {

    private Mat bgrMat;
    private int csRadius;

    public FICS(Mat bgrMat, int csRadius) {
        // TODO Auto-generated constructor stub
        this.bgrMat = bgrMat;
        this.csRadius = csRadius;
    }

    public void run() {
        // TODO Auto-generated method stub
        calcFICS(this.bgrMat, this.csRadius);
    }

    public static void calcFICS(Mat bgrMat, int csRadius) {
    // TODO Auto-generated method stub

    ArrayList<Mat> onOffCSActRegMatsList = null;
    ArrayList<Mat> offOnCSActRegMatsList = null;

    ArrayList<Mat> onOffCSFullMatsList = null;
    ArrayList<Mat> offOnCSFullMatsList = null;

    onOffCSActRegMatsList = new ArrayList<Mat>();
    offOnCSActRegMatsList = new ArrayList<Mat>();
4

3 回答 3

0

给定两个引用r1r2类型Runnable(注意r1也可以等于r2),很容易顺序运行它们,因此r1 发生前 r2

r1.run();
r2.run(); // will start when r1 has finished

这种技术称为“顺序执行”,允许您重用正在运行的线程r1(当前执行线程)以供r2以后运行,而无需任何线程同步机制,如CountDownLatch.

于 2015-05-02T15:54:04.507 回答
0

CountDownLatch如果由于某种原因你有义务这样做,你可以执行这项工作。诀窍是第一个线程必须在不等待闩锁的情况下运行,然后递减其计数器,而第二个线程必须等待闩锁。实现细节的方法有很多种,但这里有一种:

class FICSFilter {
    Mat bgrMat;
    int csRadius;

    public FICSFilter(Mat bgrMat, int csRadius) {
        this.bgrMat = bgrMat;
        this.csRadius = csRadius;
    }

    public void doFilter() {
        CountDownLatch openLatch = new CountDownLatch(0);
        CountDownLatch latch = new CountDownLatch(1);
        Thread fiCS_R3_Thread = new Thread(
                new FICS(3, openLatch, latch), "FICS_R3");
        Thread fiCS_R7_Thread = new Thread(
                new FICS(7, latch, latch), "FICS_R7");

        fiCS_R3.start();
        fiCS_R7.start();
        fics_R7.join();
    }

    private class FICS implements Runnable {

        private Mat bgrMat;
        private int csRadius;
        private CountDownLatch startLatch;
        private CountDownLatch signalLatch;

        public FICS(int csRadius, CountDownLatch startLatch,
                CountDownLatch signalLatch) {
            this.bgrMat = FICSFilter.this.bgrMat; // for clarity only
            this.csRadius = csRadius;
            this.startLatch = startLatch;         // assumed non-null
            this.signalLatch = signalLatch;       // assumed non-null
        }

        public void run() {
            startLatch.await();

            // ... perform the calculation ...

            signalLatch.countDown();
        }
    }
}

但是,如果您只需要按顺序运行作业,而这CountDownLatch只是如何完成的一个想法,那么这是一个更优越的解决方案:

class FICSFilter {
    Mat bgrMat;

    public FICSFilter(Mat bgrMat) {
        this.bgrMat = bgrMat;
    }

    public void doFilter() {
        Runnable fiCS_R3 = new FICS(this.bgrMat, 3);
        Runnable fiCS_R7 = new FICS(this.bgrMat, 7);

        fiCS_R3.run();
        fiCS_R7.run();
    }

    private class FICS implements Runnable {
        // As originally written ...
    }
}

a 的主要目的CountDownLatch是实现检查点,其中一个希望多个线程在它们中的任何一个继续进行之前都在它们的工作中达到相同的点。在这种情况下,您使用线程数初始化一个锁存器,并在检查点每个首先递减锁存器,然后等待它:

latch.countDown();
latch.await();

该构造可以应用于其他任务,例如您询问的任务,但对于某些人来说它比其他人更自然。对于您的特定任务来说,这很不自然。

于 2015-05-02T16:15:43.263 回答
0

导入 java.util.ArrayList;导入 java.util.concurrent.CountDownLatch;

公共类 FICSFilter {

Mat bgrMat;
int csRadius;


public FICSFilter(Mat bgrMat, int csRadius) {
    this.bgrMat = bgrMat;
    this.csRadius = csRadius;
    //How to use the CounDownLatch for two different threads each of them has the same runnable class
}

public static void main(String args[]){

    // CountDownLatch startLatch = new CountDownLatch(1);

    CountDownLatch doneLatch = new CountDownLatch(1);

    Mat lbgrmat = new Mat();

    Thread fiCS_R3 = new Thread(new FICS(lbgrmat, 10, doneLatch));
    Thread fiCS_R7 = new Thread(new FICS(lbgrmat, 20, null));

    fiCS_R3.start();

    try {
        System.out.println("\n Going into block state in main");
        doneLatch.await();
        System.out.println("\n Out of block state in main");

    } catch (InterruptedException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    fiCS_R7.start();
}

}

类 FICS 实现 Runnable {

CountDownLatch doneSignal;

Mat bgrMat;
int csRadius;

public FICS(Mat bgrMat, int csRadius, CountDownLatch llatch ) {
    this.bgrMat = bgrMat;
    this.csRadius = csRadius;
    this.doneSignal = llatch;
}

public void run() {
    calcFICS(this.bgrMat, this.csRadius);

}

public void calcFICS(Mat bgrMat, int csRadius)   {
    System.out.println("\n Radius : " + csRadius + " Thread : "+ Thread.currentThread().getName());
    try {
        Thread.sleep(5000);
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    if (doneSignal != null )
        doneSignal.countDown();
}

}

上面的代码阻塞在主线程中的一个闩锁上,只有当第一个线程 FICS3 完成它的工作并释放闩锁时,主线程才会启动下一个线程。

于 2015-05-07T12:44:48.283 回答