Java chain lock a bit differently












0















I have 1,2,3 threads each have A,B,C sections to run sequentially like
1A, 2A, 3A, 1B, 2B, 3B, 1C, 2C, 3C. So after 1A finishes its run it waits for the signal of thread 3 to continue with its section B and so on. How could I achieve this? I have to reuse the threads so I cannot make threads from sections.










share|improve this question

























  • what have you tried so far?

    – Scary Wombat
    Nov 13 '18 at 7:51











  • Tried to use multiple ReentrantLock, synchronized, wait, notify.

    – apreg
    Nov 13 '18 at 7:52











  • Can you post the code you have tried? And what are the results you have gotten?

    – mjuarez
    Nov 13 '18 at 7:53






  • 1





    docs.oracle.com/javase/8/docs/api/java/util/concurrent/…

    – JB Nizet
    Nov 13 '18 at 7:55






  • 1





    Do you need the sequence of 1A, 2A, 3A to stay in that order? If so, then I don't see any reason to use Threads because you have a serial application.

    – matt
    Nov 13 '18 at 8:15
















0















I have 1,2,3 threads each have A,B,C sections to run sequentially like
1A, 2A, 3A, 1B, 2B, 3B, 1C, 2C, 3C. So after 1A finishes its run it waits for the signal of thread 3 to continue with its section B and so on. How could I achieve this? I have to reuse the threads so I cannot make threads from sections.










share|improve this question

























  • what have you tried so far?

    – Scary Wombat
    Nov 13 '18 at 7:51











  • Tried to use multiple ReentrantLock, synchronized, wait, notify.

    – apreg
    Nov 13 '18 at 7:52











  • Can you post the code you have tried? And what are the results you have gotten?

    – mjuarez
    Nov 13 '18 at 7:53






  • 1





    docs.oracle.com/javase/8/docs/api/java/util/concurrent/…

    – JB Nizet
    Nov 13 '18 at 7:55






  • 1





    Do you need the sequence of 1A, 2A, 3A to stay in that order? If so, then I don't see any reason to use Threads because you have a serial application.

    – matt
    Nov 13 '18 at 8:15














0












0








0








I have 1,2,3 threads each have A,B,C sections to run sequentially like
1A, 2A, 3A, 1B, 2B, 3B, 1C, 2C, 3C. So after 1A finishes its run it waits for the signal of thread 3 to continue with its section B and so on. How could I achieve this? I have to reuse the threads so I cannot make threads from sections.










share|improve this question
















I have 1,2,3 threads each have A,B,C sections to run sequentially like
1A, 2A, 3A, 1B, 2B, 3B, 1C, 2C, 3C. So after 1A finishes its run it waits for the signal of thread 3 to continue with its section B and so on. How could I achieve this? I have to reuse the threads so I cannot make threads from sections.







java multithreading






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 13 '18 at 7:54









mjuarez

9,85973751




9,85973751










asked Nov 13 '18 at 7:51









apregapreg

327416




327416













  • what have you tried so far?

    – Scary Wombat
    Nov 13 '18 at 7:51











  • Tried to use multiple ReentrantLock, synchronized, wait, notify.

    – apreg
    Nov 13 '18 at 7:52











  • Can you post the code you have tried? And what are the results you have gotten?

    – mjuarez
    Nov 13 '18 at 7:53






  • 1





    docs.oracle.com/javase/8/docs/api/java/util/concurrent/…

    – JB Nizet
    Nov 13 '18 at 7:55






  • 1





    Do you need the sequence of 1A, 2A, 3A to stay in that order? If so, then I don't see any reason to use Threads because you have a serial application.

    – matt
    Nov 13 '18 at 8:15



















  • what have you tried so far?

    – Scary Wombat
    Nov 13 '18 at 7:51











  • Tried to use multiple ReentrantLock, synchronized, wait, notify.

    – apreg
    Nov 13 '18 at 7:52











  • Can you post the code you have tried? And what are the results you have gotten?

    – mjuarez
    Nov 13 '18 at 7:53






  • 1





    docs.oracle.com/javase/8/docs/api/java/util/concurrent/…

    – JB Nizet
    Nov 13 '18 at 7:55






  • 1





    Do you need the sequence of 1A, 2A, 3A to stay in that order? If so, then I don't see any reason to use Threads because you have a serial application.

    – matt
    Nov 13 '18 at 8:15

















what have you tried so far?

– Scary Wombat
Nov 13 '18 at 7:51





what have you tried so far?

– Scary Wombat
Nov 13 '18 at 7:51













Tried to use multiple ReentrantLock, synchronized, wait, notify.

– apreg
Nov 13 '18 at 7:52





Tried to use multiple ReentrantLock, synchronized, wait, notify.

– apreg
Nov 13 '18 at 7:52













Can you post the code you have tried? And what are the results you have gotten?

– mjuarez
Nov 13 '18 at 7:53





Can you post the code you have tried? And what are the results you have gotten?

– mjuarez
Nov 13 '18 at 7:53




1




1





docs.oracle.com/javase/8/docs/api/java/util/concurrent/…

– JB Nizet
Nov 13 '18 at 7:55





docs.oracle.com/javase/8/docs/api/java/util/concurrent/…

– JB Nizet
Nov 13 '18 at 7:55




1




1





Do you need the sequence of 1A, 2A, 3A to stay in that order? If so, then I don't see any reason to use Threads because you have a serial application.

– matt
Nov 13 '18 at 8:15





Do you need the sequence of 1A, 2A, 3A to stay in that order? If so, then I don't see any reason to use Threads because you have a serial application.

– matt
Nov 13 '18 at 8:15












4 Answers
4






active

oldest

votes


















2














That's the job of a CyclicBarrier:



public class BarrierDemo {
public static void main(String args) {
CyclicBarrier barrier = new CyclicBarrier(3); // three threads

new Thread(new Task(1, barrier)).start();
new Thread(new Task(2, barrier)).start();
new Thread(new Task(3, barrier)).start();
}

private static class Task implements Runnable {
private final int number;
private final CyclicBarrier barrier;

public Task(int number, CyclicBarrier barrier) {
this.number = number;
this.barrier = barrier;
}

@Override
public void run() {
try {
System.out.println(number + "A");
barrier.await();
System.out.println(number + "B");
barrier.await();
System.out.println(number + "C");
}
catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
catch(BrokenBarrierException e) {
// too bad
}
}
}
}





share|improve this answer



















  • 1





    Does this run the tasks in batchs (1A, 2A, 3A) then (1B, 2B, 3B) where the order of the A tasks could be in any order? The order of the B tasks could be in any order, etc.

    – matt
    Nov 13 '18 at 8:13











  • This doesn't ensure that threads will run a task in order 1,2,3

    – Maurice Perry
    Nov 13 '18 at 8:22






  • 1





    @matt yes. I assume that this is what the OP wants. Otherwise, if everything needs to be run sequentially, there is no point in using threads at all.

    – JB Nizet
    Nov 13 '18 at 17:18



















0














if order of 1,2,3 is not important , but order of all A,all B,all C is important, Then,
use 2 CountDownLatch.
you can start A section directly . when A section is done count down the CountDownLatch.



before B section starts await() the CountDownLatch.



so there should be 2 CountDownLatch latches to synchronize section B and section C.



    public class Test extends Thread
{

CountDownLatch cdlA;
CountDownLatch cdlB;
int threadId;

public Test(CountDownLatch cdlA, CountDownLatch cdlB,int threadNumber)
{
this.cdlA = cdlA;
this.cdlB = cdlB;
threadId = threadNumber;
}

@Override
public void run()
{
test();
}

private void test()
{
try
{
System.out.println("section A" +threadId);
cdlA.countDown();

cdlA.await();

System.out.println("section B" +threadId);
cdlB.countDown();

cdlB.await();

System.out.println("section C" +threadId);
}
catch (InterruptedException e)
{

}

}

public static void main(String args) throws InterruptedException
{
CountDownLatch a = new CountDownLatch(3);
CountDownLatch b = new CountDownLatch(3);

final Test test1 = new Test(a, b,1);

final Test test2 = new Test(a, b,2);

final Test test3 = new Test(a, b,3);

test1.start();
test2.start();
test3.start();
}
}





share|improve this answer

































    0














    If you have a delegate that knows what to do then you can use an executor service to control execution. Eg. create an executors service for each thread, submit, then use Future.get to wait for the execution completes.



    The otherway is to use a sort of ball.



    static public void task(int no){
    System.out.println("task " + no + " on " + Thread.currentThread().getName());
    }

    public static void main(String args) throws Exception{
    BlockingQueue<Object> permissions = new ArrayBlockingQueue<>(1);

    var A = new Thread(){
    BlockingQueue<Object> waiting = new ArrayBlockingQueue<>(1);
    public void run(){
    for(int i = 0; i<3; i++){
    Object ball = null;
    try{
    ball = waiting.take();
    task(i);
    } catch(InterruptedException e){
    throw new RuntimeException(e);
    }finally{
    permissions.offer(ball);
    }
    }
    }
    };

    var B = new Thread(){
    BlockingQueue<Object> waiting = new ArrayBlockingQueue<>(1);
    public void run(){
    for(int i = 0; i<3; i++){
    Object ball = null;
    try{
    ball = waiting.take();
    task(i);
    } catch(InterruptedException e){
    throw new RuntimeException(e);
    }finally{
    permissions.offer(ball);
    }
    }
    }
    };

    A.start();
    B.start();
    Object ball = new Object();
    A.waiting.offer(ball);
    ball = permissions.take();
    B.waiting.offer(ball);
    ball = permissions.take();
    A.waiting.offer(ball);
    ball = permissions.take();
    B.waiting.offer(ball);
    ball = permissions.take();
    A.waiting.offer(ball);
    ball = permissions.take();
    B.waiting.offer(ball);
    ball = permissions.take();
    System.out.println("finished");


    There are definitely better ways, I think you can see this is not extensible, you have to know the number of tasks. There is no actuall purpose for the Object ball, and a new Object(); could be used, or even null.






    share|improve this answer































      0














      Here is my solution for the problem. I think the idea behind it is close to matt's solution. Thank you for all you guys.



       @Test
      void test() throws InterruptedException {
      ExecutorService executor = Executors.newFixedThreadPool(3);
      SynchronousQueue<Integer> chromeQueue = new SynchronousQueue<>();
      SynchronousQueue<Integer> firefoxQueue = new SynchronousQueue<>();
      SynchronousQueue<Integer> ieQueue = new SynchronousQueue<>();

      Runnable ieRunnable = () -> {
      try {
      firefoxQueue.take();
      System.out.println("ieRunnable section 1");
      ieQueue.put(1);
      firefoxQueue.take();
      System.out.println("ieRunnable section 2");
      } catch (InterruptedException e) {
      Thread.currentThread().interrupt();
      }
      };

      Runnable firefoxRunnable = () -> {
      try {
      chromeQueue.take();
      System.out.println("firefoxRunnable section 1");
      firefoxQueue.put(1);
      chromeQueue.take();
      System.out.println("firefoxRunnable section 2");
      firefoxQueue.put(1);
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      };

      Runnable chromeRunnable = () -> {
      try {
      ieQueue.take();//waits
      System.out.println("chromeRunnable section 1");
      chromeQueue.put(1);//starts firefoxRunnable
      ieQueue.take();//wait for ieRunnable to signal
      System.out.println("chromeRunnable section 2");
      chromeQueue.put(1);//makes firefoxRunnable to continue
      } catch (InterruptedException e) {
      e.printStackTrace();
      }
      };
      executor.execute(chromeRunnable);
      executor.execute(firefoxRunnable);
      executor.execute(ieRunnable);
      ieQueue.put(1);
      executor.shutdown();
      try {
      if (!executor.awaitTermination(5, TimeUnit.MINUTES)) {
      executor.shutdownNow();
      }
      } catch (InterruptedException e) {
      executor.shutdownNow();
      }
      }





      share|improve this answer























        Your Answer






        StackExchange.ifUsing("editor", function () {
        StackExchange.using("externalEditor", function () {
        StackExchange.using("snippets", function () {
        StackExchange.snippets.init();
        });
        });
        }, "code-snippets");

        StackExchange.ready(function() {
        var channelOptions = {
        tags: "".split(" "),
        id: "1"
        };
        initTagRenderer("".split(" "), "".split(" "), channelOptions);

        StackExchange.using("externalEditor", function() {
        // Have to fire editor after snippets, if snippets enabled
        if (StackExchange.settings.snippets.snippetsEnabled) {
        StackExchange.using("snippets", function() {
        createEditor();
        });
        }
        else {
        createEditor();
        }
        });

        function createEditor() {
        StackExchange.prepareEditor({
        heartbeatType: 'answer',
        autoActivateHeartbeat: false,
        convertImagesToLinks: true,
        noModals: true,
        showLowRepImageUploadWarning: true,
        reputationToPostImages: 10,
        bindNavPrevention: true,
        postfix: "",
        imageUploader: {
        brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
        contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
        allowUrls: true
        },
        onDemand: true,
        discardSelector: ".discard-answer"
        ,immediatelyShowMarkdownHelp:true
        });


        }
        });














        draft saved

        draft discarded


















        StackExchange.ready(
        function () {
        StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53276201%2fjava-chain-lock-a-bit-differently%23new-answer', 'question_page');
        }
        );

        Post as a guest















        Required, but never shown

























        4 Answers
        4






        active

        oldest

        votes








        4 Answers
        4






        active

        oldest

        votes









        active

        oldest

        votes






        active

        oldest

        votes









        2














        That's the job of a CyclicBarrier:



        public class BarrierDemo {
        public static void main(String args) {
        CyclicBarrier barrier = new CyclicBarrier(3); // three threads

        new Thread(new Task(1, barrier)).start();
        new Thread(new Task(2, barrier)).start();
        new Thread(new Task(3, barrier)).start();
        }

        private static class Task implements Runnable {
        private final int number;
        private final CyclicBarrier barrier;

        public Task(int number, CyclicBarrier barrier) {
        this.number = number;
        this.barrier = barrier;
        }

        @Override
        public void run() {
        try {
        System.out.println(number + "A");
        barrier.await();
        System.out.println(number + "B");
        barrier.await();
        System.out.println(number + "C");
        }
        catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        }
        catch(BrokenBarrierException e) {
        // too bad
        }
        }
        }
        }





        share|improve this answer



















        • 1





          Does this run the tasks in batchs (1A, 2A, 3A) then (1B, 2B, 3B) where the order of the A tasks could be in any order? The order of the B tasks could be in any order, etc.

          – matt
          Nov 13 '18 at 8:13











        • This doesn't ensure that threads will run a task in order 1,2,3

          – Maurice Perry
          Nov 13 '18 at 8:22






        • 1





          @matt yes. I assume that this is what the OP wants. Otherwise, if everything needs to be run sequentially, there is no point in using threads at all.

          – JB Nizet
          Nov 13 '18 at 17:18
















        2














        That's the job of a CyclicBarrier:



        public class BarrierDemo {
        public static void main(String args) {
        CyclicBarrier barrier = new CyclicBarrier(3); // three threads

        new Thread(new Task(1, barrier)).start();
        new Thread(new Task(2, barrier)).start();
        new Thread(new Task(3, barrier)).start();
        }

        private static class Task implements Runnable {
        private final int number;
        private final CyclicBarrier barrier;

        public Task(int number, CyclicBarrier barrier) {
        this.number = number;
        this.barrier = barrier;
        }

        @Override
        public void run() {
        try {
        System.out.println(number + "A");
        barrier.await();
        System.out.println(number + "B");
        barrier.await();
        System.out.println(number + "C");
        }
        catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        }
        catch(BrokenBarrierException e) {
        // too bad
        }
        }
        }
        }





        share|improve this answer



















        • 1





          Does this run the tasks in batchs (1A, 2A, 3A) then (1B, 2B, 3B) where the order of the A tasks could be in any order? The order of the B tasks could be in any order, etc.

          – matt
          Nov 13 '18 at 8:13











        • This doesn't ensure that threads will run a task in order 1,2,3

          – Maurice Perry
          Nov 13 '18 at 8:22






        • 1





          @matt yes. I assume that this is what the OP wants. Otherwise, if everything needs to be run sequentially, there is no point in using threads at all.

          – JB Nizet
          Nov 13 '18 at 17:18














        2












        2








        2







        That's the job of a CyclicBarrier:



        public class BarrierDemo {
        public static void main(String args) {
        CyclicBarrier barrier = new CyclicBarrier(3); // three threads

        new Thread(new Task(1, barrier)).start();
        new Thread(new Task(2, barrier)).start();
        new Thread(new Task(3, barrier)).start();
        }

        private static class Task implements Runnable {
        private final int number;
        private final CyclicBarrier barrier;

        public Task(int number, CyclicBarrier barrier) {
        this.number = number;
        this.barrier = barrier;
        }

        @Override
        public void run() {
        try {
        System.out.println(number + "A");
        barrier.await();
        System.out.println(number + "B");
        barrier.await();
        System.out.println(number + "C");
        }
        catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        }
        catch(BrokenBarrierException e) {
        // too bad
        }
        }
        }
        }





        share|improve this answer













        That's the job of a CyclicBarrier:



        public class BarrierDemo {
        public static void main(String args) {
        CyclicBarrier barrier = new CyclicBarrier(3); // three threads

        new Thread(new Task(1, barrier)).start();
        new Thread(new Task(2, barrier)).start();
        new Thread(new Task(3, barrier)).start();
        }

        private static class Task implements Runnable {
        private final int number;
        private final CyclicBarrier barrier;

        public Task(int number, CyclicBarrier barrier) {
        this.number = number;
        this.barrier = barrier;
        }

        @Override
        public void run() {
        try {
        System.out.println(number + "A");
        barrier.await();
        System.out.println(number + "B");
        barrier.await();
        System.out.println(number + "C");
        }
        catch (InterruptedException e) {
        Thread.currentThread().interrupt();
        }
        catch(BrokenBarrierException e) {
        // too bad
        }
        }
        }
        }






        share|improve this answer












        share|improve this answer



        share|improve this answer










        answered Nov 13 '18 at 8:02









        JB NizetJB Nizet

        537k55867999




        537k55867999








        • 1





          Does this run the tasks in batchs (1A, 2A, 3A) then (1B, 2B, 3B) where the order of the A tasks could be in any order? The order of the B tasks could be in any order, etc.

          – matt
          Nov 13 '18 at 8:13











        • This doesn't ensure that threads will run a task in order 1,2,3

          – Maurice Perry
          Nov 13 '18 at 8:22






        • 1





          @matt yes. I assume that this is what the OP wants. Otherwise, if everything needs to be run sequentially, there is no point in using threads at all.

          – JB Nizet
          Nov 13 '18 at 17:18














        • 1





          Does this run the tasks in batchs (1A, 2A, 3A) then (1B, 2B, 3B) where the order of the A tasks could be in any order? The order of the B tasks could be in any order, etc.

          – matt
          Nov 13 '18 at 8:13











        • This doesn't ensure that threads will run a task in order 1,2,3

          – Maurice Perry
          Nov 13 '18 at 8:22






        • 1





          @matt yes. I assume that this is what the OP wants. Otherwise, if everything needs to be run sequentially, there is no point in using threads at all.

          – JB Nizet
          Nov 13 '18 at 17:18








        1




        1





        Does this run the tasks in batchs (1A, 2A, 3A) then (1B, 2B, 3B) where the order of the A tasks could be in any order? The order of the B tasks could be in any order, etc.

        – matt
        Nov 13 '18 at 8:13





        Does this run the tasks in batchs (1A, 2A, 3A) then (1B, 2B, 3B) where the order of the A tasks could be in any order? The order of the B tasks could be in any order, etc.

        – matt
        Nov 13 '18 at 8:13













        This doesn't ensure that threads will run a task in order 1,2,3

        – Maurice Perry
        Nov 13 '18 at 8:22





        This doesn't ensure that threads will run a task in order 1,2,3

        – Maurice Perry
        Nov 13 '18 at 8:22




        1




        1





        @matt yes. I assume that this is what the OP wants. Otherwise, if everything needs to be run sequentially, there is no point in using threads at all.

        – JB Nizet
        Nov 13 '18 at 17:18





        @matt yes. I assume that this is what the OP wants. Otherwise, if everything needs to be run sequentially, there is no point in using threads at all.

        – JB Nizet
        Nov 13 '18 at 17:18













        0














        if order of 1,2,3 is not important , but order of all A,all B,all C is important, Then,
        use 2 CountDownLatch.
        you can start A section directly . when A section is done count down the CountDownLatch.



        before B section starts await() the CountDownLatch.



        so there should be 2 CountDownLatch latches to synchronize section B and section C.



            public class Test extends Thread
        {

        CountDownLatch cdlA;
        CountDownLatch cdlB;
        int threadId;

        public Test(CountDownLatch cdlA, CountDownLatch cdlB,int threadNumber)
        {
        this.cdlA = cdlA;
        this.cdlB = cdlB;
        threadId = threadNumber;
        }

        @Override
        public void run()
        {
        test();
        }

        private void test()
        {
        try
        {
        System.out.println("section A" +threadId);
        cdlA.countDown();

        cdlA.await();

        System.out.println("section B" +threadId);
        cdlB.countDown();

        cdlB.await();

        System.out.println("section C" +threadId);
        }
        catch (InterruptedException e)
        {

        }

        }

        public static void main(String args) throws InterruptedException
        {
        CountDownLatch a = new CountDownLatch(3);
        CountDownLatch b = new CountDownLatch(3);

        final Test test1 = new Test(a, b,1);

        final Test test2 = new Test(a, b,2);

        final Test test3 = new Test(a, b,3);

        test1.start();
        test2.start();
        test3.start();
        }
        }





        share|improve this answer






























          0














          if order of 1,2,3 is not important , but order of all A,all B,all C is important, Then,
          use 2 CountDownLatch.
          you can start A section directly . when A section is done count down the CountDownLatch.



          before B section starts await() the CountDownLatch.



          so there should be 2 CountDownLatch latches to synchronize section B and section C.



              public class Test extends Thread
          {

          CountDownLatch cdlA;
          CountDownLatch cdlB;
          int threadId;

          public Test(CountDownLatch cdlA, CountDownLatch cdlB,int threadNumber)
          {
          this.cdlA = cdlA;
          this.cdlB = cdlB;
          threadId = threadNumber;
          }

          @Override
          public void run()
          {
          test();
          }

          private void test()
          {
          try
          {
          System.out.println("section A" +threadId);
          cdlA.countDown();

          cdlA.await();

          System.out.println("section B" +threadId);
          cdlB.countDown();

          cdlB.await();

          System.out.println("section C" +threadId);
          }
          catch (InterruptedException e)
          {

          }

          }

          public static void main(String args) throws InterruptedException
          {
          CountDownLatch a = new CountDownLatch(3);
          CountDownLatch b = new CountDownLatch(3);

          final Test test1 = new Test(a, b,1);

          final Test test2 = new Test(a, b,2);

          final Test test3 = new Test(a, b,3);

          test1.start();
          test2.start();
          test3.start();
          }
          }





          share|improve this answer




























            0












            0








            0







            if order of 1,2,3 is not important , but order of all A,all B,all C is important, Then,
            use 2 CountDownLatch.
            you can start A section directly . when A section is done count down the CountDownLatch.



            before B section starts await() the CountDownLatch.



            so there should be 2 CountDownLatch latches to synchronize section B and section C.



                public class Test extends Thread
            {

            CountDownLatch cdlA;
            CountDownLatch cdlB;
            int threadId;

            public Test(CountDownLatch cdlA, CountDownLatch cdlB,int threadNumber)
            {
            this.cdlA = cdlA;
            this.cdlB = cdlB;
            threadId = threadNumber;
            }

            @Override
            public void run()
            {
            test();
            }

            private void test()
            {
            try
            {
            System.out.println("section A" +threadId);
            cdlA.countDown();

            cdlA.await();

            System.out.println("section B" +threadId);
            cdlB.countDown();

            cdlB.await();

            System.out.println("section C" +threadId);
            }
            catch (InterruptedException e)
            {

            }

            }

            public static void main(String args) throws InterruptedException
            {
            CountDownLatch a = new CountDownLatch(3);
            CountDownLatch b = new CountDownLatch(3);

            final Test test1 = new Test(a, b,1);

            final Test test2 = new Test(a, b,2);

            final Test test3 = new Test(a, b,3);

            test1.start();
            test2.start();
            test3.start();
            }
            }





            share|improve this answer















            if order of 1,2,3 is not important , but order of all A,all B,all C is important, Then,
            use 2 CountDownLatch.
            you can start A section directly . when A section is done count down the CountDownLatch.



            before B section starts await() the CountDownLatch.



            so there should be 2 CountDownLatch latches to synchronize section B and section C.



                public class Test extends Thread
            {

            CountDownLatch cdlA;
            CountDownLatch cdlB;
            int threadId;

            public Test(CountDownLatch cdlA, CountDownLatch cdlB,int threadNumber)
            {
            this.cdlA = cdlA;
            this.cdlB = cdlB;
            threadId = threadNumber;
            }

            @Override
            public void run()
            {
            test();
            }

            private void test()
            {
            try
            {
            System.out.println("section A" +threadId);
            cdlA.countDown();

            cdlA.await();

            System.out.println("section B" +threadId);
            cdlB.countDown();

            cdlB.await();

            System.out.println("section C" +threadId);
            }
            catch (InterruptedException e)
            {

            }

            }

            public static void main(String args) throws InterruptedException
            {
            CountDownLatch a = new CountDownLatch(3);
            CountDownLatch b = new CountDownLatch(3);

            final Test test1 = new Test(a, b,1);

            final Test test2 = new Test(a, b,2);

            final Test test3 = new Test(a, b,3);

            test1.start();
            test2.start();
            test3.start();
            }
            }






            share|improve this answer














            share|improve this answer



            share|improve this answer








            edited Nov 13 '18 at 9:13

























            answered Nov 13 '18 at 8:09









            hunterhunter

            1,584715




            1,584715























                0














                If you have a delegate that knows what to do then you can use an executor service to control execution. Eg. create an executors service for each thread, submit, then use Future.get to wait for the execution completes.



                The otherway is to use a sort of ball.



                static public void task(int no){
                System.out.println("task " + no + " on " + Thread.currentThread().getName());
                }

                public static void main(String args) throws Exception{
                BlockingQueue<Object> permissions = new ArrayBlockingQueue<>(1);

                var A = new Thread(){
                BlockingQueue<Object> waiting = new ArrayBlockingQueue<>(1);
                public void run(){
                for(int i = 0; i<3; i++){
                Object ball = null;
                try{
                ball = waiting.take();
                task(i);
                } catch(InterruptedException e){
                throw new RuntimeException(e);
                }finally{
                permissions.offer(ball);
                }
                }
                }
                };

                var B = new Thread(){
                BlockingQueue<Object> waiting = new ArrayBlockingQueue<>(1);
                public void run(){
                for(int i = 0; i<3; i++){
                Object ball = null;
                try{
                ball = waiting.take();
                task(i);
                } catch(InterruptedException e){
                throw new RuntimeException(e);
                }finally{
                permissions.offer(ball);
                }
                }
                }
                };

                A.start();
                B.start();
                Object ball = new Object();
                A.waiting.offer(ball);
                ball = permissions.take();
                B.waiting.offer(ball);
                ball = permissions.take();
                A.waiting.offer(ball);
                ball = permissions.take();
                B.waiting.offer(ball);
                ball = permissions.take();
                A.waiting.offer(ball);
                ball = permissions.take();
                B.waiting.offer(ball);
                ball = permissions.take();
                System.out.println("finished");


                There are definitely better ways, I think you can see this is not extensible, you have to know the number of tasks. There is no actuall purpose for the Object ball, and a new Object(); could be used, or even null.






                share|improve this answer




























                  0














                  If you have a delegate that knows what to do then you can use an executor service to control execution. Eg. create an executors service for each thread, submit, then use Future.get to wait for the execution completes.



                  The otherway is to use a sort of ball.



                  static public void task(int no){
                  System.out.println("task " + no + " on " + Thread.currentThread().getName());
                  }

                  public static void main(String args) throws Exception{
                  BlockingQueue<Object> permissions = new ArrayBlockingQueue<>(1);

                  var A = new Thread(){
                  BlockingQueue<Object> waiting = new ArrayBlockingQueue<>(1);
                  public void run(){
                  for(int i = 0; i<3; i++){
                  Object ball = null;
                  try{
                  ball = waiting.take();
                  task(i);
                  } catch(InterruptedException e){
                  throw new RuntimeException(e);
                  }finally{
                  permissions.offer(ball);
                  }
                  }
                  }
                  };

                  var B = new Thread(){
                  BlockingQueue<Object> waiting = new ArrayBlockingQueue<>(1);
                  public void run(){
                  for(int i = 0; i<3; i++){
                  Object ball = null;
                  try{
                  ball = waiting.take();
                  task(i);
                  } catch(InterruptedException e){
                  throw new RuntimeException(e);
                  }finally{
                  permissions.offer(ball);
                  }
                  }
                  }
                  };

                  A.start();
                  B.start();
                  Object ball = new Object();
                  A.waiting.offer(ball);
                  ball = permissions.take();
                  B.waiting.offer(ball);
                  ball = permissions.take();
                  A.waiting.offer(ball);
                  ball = permissions.take();
                  B.waiting.offer(ball);
                  ball = permissions.take();
                  A.waiting.offer(ball);
                  ball = permissions.take();
                  B.waiting.offer(ball);
                  ball = permissions.take();
                  System.out.println("finished");


                  There are definitely better ways, I think you can see this is not extensible, you have to know the number of tasks. There is no actuall purpose for the Object ball, and a new Object(); could be used, or even null.






                  share|improve this answer


























                    0












                    0








                    0







                    If you have a delegate that knows what to do then you can use an executor service to control execution. Eg. create an executors service for each thread, submit, then use Future.get to wait for the execution completes.



                    The otherway is to use a sort of ball.



                    static public void task(int no){
                    System.out.println("task " + no + " on " + Thread.currentThread().getName());
                    }

                    public static void main(String args) throws Exception{
                    BlockingQueue<Object> permissions = new ArrayBlockingQueue<>(1);

                    var A = new Thread(){
                    BlockingQueue<Object> waiting = new ArrayBlockingQueue<>(1);
                    public void run(){
                    for(int i = 0; i<3; i++){
                    Object ball = null;
                    try{
                    ball = waiting.take();
                    task(i);
                    } catch(InterruptedException e){
                    throw new RuntimeException(e);
                    }finally{
                    permissions.offer(ball);
                    }
                    }
                    }
                    };

                    var B = new Thread(){
                    BlockingQueue<Object> waiting = new ArrayBlockingQueue<>(1);
                    public void run(){
                    for(int i = 0; i<3; i++){
                    Object ball = null;
                    try{
                    ball = waiting.take();
                    task(i);
                    } catch(InterruptedException e){
                    throw new RuntimeException(e);
                    }finally{
                    permissions.offer(ball);
                    }
                    }
                    }
                    };

                    A.start();
                    B.start();
                    Object ball = new Object();
                    A.waiting.offer(ball);
                    ball = permissions.take();
                    B.waiting.offer(ball);
                    ball = permissions.take();
                    A.waiting.offer(ball);
                    ball = permissions.take();
                    B.waiting.offer(ball);
                    ball = permissions.take();
                    A.waiting.offer(ball);
                    ball = permissions.take();
                    B.waiting.offer(ball);
                    ball = permissions.take();
                    System.out.println("finished");


                    There are definitely better ways, I think you can see this is not extensible, you have to know the number of tasks. There is no actuall purpose for the Object ball, and a new Object(); could be used, or even null.






                    share|improve this answer













                    If you have a delegate that knows what to do then you can use an executor service to control execution. Eg. create an executors service for each thread, submit, then use Future.get to wait for the execution completes.



                    The otherway is to use a sort of ball.



                    static public void task(int no){
                    System.out.println("task " + no + " on " + Thread.currentThread().getName());
                    }

                    public static void main(String args) throws Exception{
                    BlockingQueue<Object> permissions = new ArrayBlockingQueue<>(1);

                    var A = new Thread(){
                    BlockingQueue<Object> waiting = new ArrayBlockingQueue<>(1);
                    public void run(){
                    for(int i = 0; i<3; i++){
                    Object ball = null;
                    try{
                    ball = waiting.take();
                    task(i);
                    } catch(InterruptedException e){
                    throw new RuntimeException(e);
                    }finally{
                    permissions.offer(ball);
                    }
                    }
                    }
                    };

                    var B = new Thread(){
                    BlockingQueue<Object> waiting = new ArrayBlockingQueue<>(1);
                    public void run(){
                    for(int i = 0; i<3; i++){
                    Object ball = null;
                    try{
                    ball = waiting.take();
                    task(i);
                    } catch(InterruptedException e){
                    throw new RuntimeException(e);
                    }finally{
                    permissions.offer(ball);
                    }
                    }
                    }
                    };

                    A.start();
                    B.start();
                    Object ball = new Object();
                    A.waiting.offer(ball);
                    ball = permissions.take();
                    B.waiting.offer(ball);
                    ball = permissions.take();
                    A.waiting.offer(ball);
                    ball = permissions.take();
                    B.waiting.offer(ball);
                    ball = permissions.take();
                    A.waiting.offer(ball);
                    ball = permissions.take();
                    B.waiting.offer(ball);
                    ball = permissions.take();
                    System.out.println("finished");


                    There are definitely better ways, I think you can see this is not extensible, you have to know the number of tasks. There is no actuall purpose for the Object ball, and a new Object(); could be used, or even null.







                    share|improve this answer












                    share|improve this answer



                    share|improve this answer










                    answered Nov 13 '18 at 19:24









                    mattmatt

                    4,2551923




                    4,2551923























                        0














                        Here is my solution for the problem. I think the idea behind it is close to matt's solution. Thank you for all you guys.



                         @Test
                        void test() throws InterruptedException {
                        ExecutorService executor = Executors.newFixedThreadPool(3);
                        SynchronousQueue<Integer> chromeQueue = new SynchronousQueue<>();
                        SynchronousQueue<Integer> firefoxQueue = new SynchronousQueue<>();
                        SynchronousQueue<Integer> ieQueue = new SynchronousQueue<>();

                        Runnable ieRunnable = () -> {
                        try {
                        firefoxQueue.take();
                        System.out.println("ieRunnable section 1");
                        ieQueue.put(1);
                        firefoxQueue.take();
                        System.out.println("ieRunnable section 2");
                        } catch (InterruptedException e) {
                        Thread.currentThread().interrupt();
                        }
                        };

                        Runnable firefoxRunnable = () -> {
                        try {
                        chromeQueue.take();
                        System.out.println("firefoxRunnable section 1");
                        firefoxQueue.put(1);
                        chromeQueue.take();
                        System.out.println("firefoxRunnable section 2");
                        firefoxQueue.put(1);
                        } catch (InterruptedException e) {
                        e.printStackTrace();
                        }
                        };

                        Runnable chromeRunnable = () -> {
                        try {
                        ieQueue.take();//waits
                        System.out.println("chromeRunnable section 1");
                        chromeQueue.put(1);//starts firefoxRunnable
                        ieQueue.take();//wait for ieRunnable to signal
                        System.out.println("chromeRunnable section 2");
                        chromeQueue.put(1);//makes firefoxRunnable to continue
                        } catch (InterruptedException e) {
                        e.printStackTrace();
                        }
                        };
                        executor.execute(chromeRunnable);
                        executor.execute(firefoxRunnable);
                        executor.execute(ieRunnable);
                        ieQueue.put(1);
                        executor.shutdown();
                        try {
                        if (!executor.awaitTermination(5, TimeUnit.MINUTES)) {
                        executor.shutdownNow();
                        }
                        } catch (InterruptedException e) {
                        executor.shutdownNow();
                        }
                        }





                        share|improve this answer




























                          0














                          Here is my solution for the problem. I think the idea behind it is close to matt's solution. Thank you for all you guys.



                           @Test
                          void test() throws InterruptedException {
                          ExecutorService executor = Executors.newFixedThreadPool(3);
                          SynchronousQueue<Integer> chromeQueue = new SynchronousQueue<>();
                          SynchronousQueue<Integer> firefoxQueue = new SynchronousQueue<>();
                          SynchronousQueue<Integer> ieQueue = new SynchronousQueue<>();

                          Runnable ieRunnable = () -> {
                          try {
                          firefoxQueue.take();
                          System.out.println("ieRunnable section 1");
                          ieQueue.put(1);
                          firefoxQueue.take();
                          System.out.println("ieRunnable section 2");
                          } catch (InterruptedException e) {
                          Thread.currentThread().interrupt();
                          }
                          };

                          Runnable firefoxRunnable = () -> {
                          try {
                          chromeQueue.take();
                          System.out.println("firefoxRunnable section 1");
                          firefoxQueue.put(1);
                          chromeQueue.take();
                          System.out.println("firefoxRunnable section 2");
                          firefoxQueue.put(1);
                          } catch (InterruptedException e) {
                          e.printStackTrace();
                          }
                          };

                          Runnable chromeRunnable = () -> {
                          try {
                          ieQueue.take();//waits
                          System.out.println("chromeRunnable section 1");
                          chromeQueue.put(1);//starts firefoxRunnable
                          ieQueue.take();//wait for ieRunnable to signal
                          System.out.println("chromeRunnable section 2");
                          chromeQueue.put(1);//makes firefoxRunnable to continue
                          } catch (InterruptedException e) {
                          e.printStackTrace();
                          }
                          };
                          executor.execute(chromeRunnable);
                          executor.execute(firefoxRunnable);
                          executor.execute(ieRunnable);
                          ieQueue.put(1);
                          executor.shutdown();
                          try {
                          if (!executor.awaitTermination(5, TimeUnit.MINUTES)) {
                          executor.shutdownNow();
                          }
                          } catch (InterruptedException e) {
                          executor.shutdownNow();
                          }
                          }





                          share|improve this answer


























                            0












                            0








                            0







                            Here is my solution for the problem. I think the idea behind it is close to matt's solution. Thank you for all you guys.



                             @Test
                            void test() throws InterruptedException {
                            ExecutorService executor = Executors.newFixedThreadPool(3);
                            SynchronousQueue<Integer> chromeQueue = new SynchronousQueue<>();
                            SynchronousQueue<Integer> firefoxQueue = new SynchronousQueue<>();
                            SynchronousQueue<Integer> ieQueue = new SynchronousQueue<>();

                            Runnable ieRunnable = () -> {
                            try {
                            firefoxQueue.take();
                            System.out.println("ieRunnable section 1");
                            ieQueue.put(1);
                            firefoxQueue.take();
                            System.out.println("ieRunnable section 2");
                            } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            }
                            };

                            Runnable firefoxRunnable = () -> {
                            try {
                            chromeQueue.take();
                            System.out.println("firefoxRunnable section 1");
                            firefoxQueue.put(1);
                            chromeQueue.take();
                            System.out.println("firefoxRunnable section 2");
                            firefoxQueue.put(1);
                            } catch (InterruptedException e) {
                            e.printStackTrace();
                            }
                            };

                            Runnable chromeRunnable = () -> {
                            try {
                            ieQueue.take();//waits
                            System.out.println("chromeRunnable section 1");
                            chromeQueue.put(1);//starts firefoxRunnable
                            ieQueue.take();//wait for ieRunnable to signal
                            System.out.println("chromeRunnable section 2");
                            chromeQueue.put(1);//makes firefoxRunnable to continue
                            } catch (InterruptedException e) {
                            e.printStackTrace();
                            }
                            };
                            executor.execute(chromeRunnable);
                            executor.execute(firefoxRunnable);
                            executor.execute(ieRunnable);
                            ieQueue.put(1);
                            executor.shutdown();
                            try {
                            if (!executor.awaitTermination(5, TimeUnit.MINUTES)) {
                            executor.shutdownNow();
                            }
                            } catch (InterruptedException e) {
                            executor.shutdownNow();
                            }
                            }





                            share|improve this answer













                            Here is my solution for the problem. I think the idea behind it is close to matt's solution. Thank you for all you guys.



                             @Test
                            void test() throws InterruptedException {
                            ExecutorService executor = Executors.newFixedThreadPool(3);
                            SynchronousQueue<Integer> chromeQueue = new SynchronousQueue<>();
                            SynchronousQueue<Integer> firefoxQueue = new SynchronousQueue<>();
                            SynchronousQueue<Integer> ieQueue = new SynchronousQueue<>();

                            Runnable ieRunnable = () -> {
                            try {
                            firefoxQueue.take();
                            System.out.println("ieRunnable section 1");
                            ieQueue.put(1);
                            firefoxQueue.take();
                            System.out.println("ieRunnable section 2");
                            } catch (InterruptedException e) {
                            Thread.currentThread().interrupt();
                            }
                            };

                            Runnable firefoxRunnable = () -> {
                            try {
                            chromeQueue.take();
                            System.out.println("firefoxRunnable section 1");
                            firefoxQueue.put(1);
                            chromeQueue.take();
                            System.out.println("firefoxRunnable section 2");
                            firefoxQueue.put(1);
                            } catch (InterruptedException e) {
                            e.printStackTrace();
                            }
                            };

                            Runnable chromeRunnable = () -> {
                            try {
                            ieQueue.take();//waits
                            System.out.println("chromeRunnable section 1");
                            chromeQueue.put(1);//starts firefoxRunnable
                            ieQueue.take();//wait for ieRunnable to signal
                            System.out.println("chromeRunnable section 2");
                            chromeQueue.put(1);//makes firefoxRunnable to continue
                            } catch (InterruptedException e) {
                            e.printStackTrace();
                            }
                            };
                            executor.execute(chromeRunnable);
                            executor.execute(firefoxRunnable);
                            executor.execute(ieRunnable);
                            ieQueue.put(1);
                            executor.shutdown();
                            try {
                            if (!executor.awaitTermination(5, TimeUnit.MINUTES)) {
                            executor.shutdownNow();
                            }
                            } catch (InterruptedException e) {
                            executor.shutdownNow();
                            }
                            }






                            share|improve this answer












                            share|improve this answer



                            share|improve this answer










                            answered Nov 14 '18 at 5:24









                            apregapreg

                            327416




                            327416






























                                draft saved

                                draft discarded




















































                                Thanks for contributing an answer to Stack Overflow!


                                • Please be sure to answer the question. Provide details and share your research!

                                But avoid



                                • Asking for help, clarification, or responding to other answers.

                                • Making statements based on opinion; back them up with references or personal experience.


                                To learn more, see our tips on writing great answers.




                                draft saved


                                draft discarded














                                StackExchange.ready(
                                function () {
                                StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53276201%2fjava-chain-lock-a-bit-differently%23new-answer', 'question_page');
                                }
                                );

                                Post as a guest















                                Required, but never shown





















































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown

































                                Required, but never shown














                                Required, but never shown












                                Required, but never shown







                                Required, but never shown







                                Popular posts from this blog

                                Florida Star v. B. J. F.

                                Danny Elfman

                                Lugert, Oklahoma