Java chain lock a bit differently
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
|
show 3 more comments
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
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
|
show 3 more comments
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
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
java multithreading
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
|
show 3 more comments
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
|
show 3 more comments
4 Answers
4
active
oldest
votes
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
}
}
}
}
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
add a comment |
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();
}
}
add a comment |
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.
add a comment |
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();
}
}
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
}
}
}
}
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
add a comment |
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
}
}
}
}
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
add a comment |
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
}
}
}
}
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
}
}
}
}
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
add a comment |
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
add a comment |
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();
}
}
add a comment |
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();
}
}
add a comment |
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();
}
}
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();
}
}
edited Nov 13 '18 at 9:13
answered Nov 13 '18 at 8:09
hunterhunter
1,584715
1,584715
add a comment |
add a comment |
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.
add a comment |
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.
add a comment |
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.
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.
answered Nov 13 '18 at 19:24
mattmatt
4,2551923
4,2551923
add a comment |
add a comment |
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();
}
}
add a comment |
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();
}
}
add a comment |
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();
}
}
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();
}
}
answered Nov 14 '18 at 5:24
apregapreg
327416
327416
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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