Last active
December 14, 2015 18:39
-
-
Save cykl/5131021 to your computer and use it in GitHub Desktop.
Demonstrate how to use Semaphore, Exchanger and CyclicBarrier to achieve following behavior: * two cooperating threads * mutual exclusion * Each thread execute after the other following a strict round robin schedule
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package info.unportant.test.testnb; | |
import java.util.concurrent.CyclicBarrier; | |
public class CyclicBarrierExample { | |
static private void sleep(String msg) { | |
int msec = (int) (Math.random() * 1000); | |
System.out.println(msg + " sleep"); | |
try { | |
Thread.sleep(msec); | |
} catch (InterruptedException e) { | |
} | |
} | |
public static void main(String[] args) { | |
ThreadCoordinator tc = new ThreadCoordinator( | |
new Runnable() { | |
public void run() { | |
sleep("main"); | |
} | |
}, | |
new Runnable() { | |
public void run() { | |
sleep("secondary"); | |
} | |
}); | |
tc.start(); | |
try { | |
Thread.sleep(60000); | |
} catch (InterruptedException e) { | |
} finally { | |
tc.stop(); | |
} | |
} | |
static class ThreadCoordinator { | |
final CyclicBarrier barrier; | |
final Runnable r1; | |
final private Runnable r2; | |
boolean stop = false; | |
public ThreadCoordinator(Runnable r1, Runnable r2) { | |
this.barrier = new CyclicBarrier(2); | |
this.r1 = r1; | |
this.r2 = r2; | |
} | |
public void stop() { | |
stop = true; | |
} | |
public void start() { | |
new Thread() { | |
@Override | |
public void run() { | |
try { | |
while (!stop) { | |
r1.run(); | |
barrier.await(); | |
// Do nothing | |
barrier.await(); | |
} | |
} catch (Exception e) { | |
} | |
} | |
}.start(); | |
new Thread() { | |
@Override | |
public void run() { | |
try { | |
while (!stop) { | |
// Do nothing | |
barrier.await(); | |
r2.run(); | |
barrier.await(); | |
} | |
} catch (Exception e) { | |
} | |
} | |
}.start(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package info.unportant.test.testnb; | |
import java.util.concurrent.Exchanger; | |
public class ExchangerExample { | |
static private void sleep(String msg) { | |
int msec = (int) (Math.random() * 1000); | |
System.out.println(msg + " sleep"); | |
try { | |
Thread.sleep(msec); | |
} catch (InterruptedException e) { | |
} | |
} | |
public static void main(String[] args) { | |
ThreadCoordinator tc = new ThreadCoordinator( | |
new Runnable() { | |
public void run() { | |
sleep("main"); | |
} | |
}, | |
new Runnable() { | |
public void run() { | |
sleep("secondary"); | |
} | |
}); | |
tc.start(); | |
try { | |
Thread.sleep(60000); | |
} catch (InterruptedException e) { | |
} finally { | |
tc.stop(); | |
} | |
} | |
static class ThreadCoordinator { | |
final Exchanger<Object> ex; | |
final Runnable r1; | |
final private Runnable r2; | |
boolean stop = false; | |
public ThreadCoordinator(Runnable r1, Runnable r2) { | |
this.ex = new Exchanger<Object>(); | |
this.r1 = r1; | |
this.r2 = r2; | |
} | |
public void stop() { | |
stop = true; | |
} | |
public void start() { | |
new Thread() { | |
@Override | |
public void run() { | |
try { | |
while (!stop) { | |
r1.run(); | |
ex.exchange(null); | |
// Do nothing | |
ex.exchange(null); | |
} | |
} catch (InterruptedException e) { | |
} | |
} | |
}.start(); | |
new Thread() { | |
@Override | |
public void run() { | |
try { | |
while (!stop) { | |
// Do nothing | |
ex.exchange(null); | |
r2.run(); | |
ex.exchange(null); | |
} | |
} catch (InterruptedException e) { | |
} | |
} | |
}.start(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package info.unportant.test.testnb; | |
import java.util.concurrent.Semaphore; | |
public class SemaphoreExample { | |
static private void sleep(String msg) { | |
int msec = (int) (Math.random() * 1000); | |
System.out.println(msg + " sleep"); | |
try { | |
Thread.sleep(msec); | |
} catch (InterruptedException e) { | |
} | |
} | |
public static void main(String[] args) { | |
ThreadCoordinator tc = new ThreadCoordinator( | |
new Runnable() { | |
public void run() { | |
sleep("main"); | |
} | |
}, | |
new Runnable() { | |
public void run() { | |
sleep("secondary"); | |
} | |
}); | |
tc.start(); | |
try { | |
Thread.sleep(60000); | |
} catch (InterruptedException e) { | |
} finally { | |
tc.stop(); | |
} | |
} | |
static class ThreadCoordinator { | |
final Semaphore s1; | |
final Semaphore s2; | |
final private Runnable r1; | |
final private Runnable r2; | |
boolean stop = false; | |
public ThreadCoordinator(Runnable r1, Runnable r2) { | |
this.s1 = new Semaphore(1); | |
this.s2 = new Semaphore(0); | |
this.r1 = r1; | |
this.r2 = r2; | |
} | |
public void stop() { | |
stop = true; | |
} | |
public void start() { | |
new Thread() { | |
@Override | |
public void run() { | |
while (!stop) { | |
s1.acquireUninterruptibly(); | |
r1.run(); | |
s2.release(); | |
} | |
} | |
}.start(); | |
new Thread() { | |
@Override | |
public void run() { | |
while (!stop) { | |
s2.acquireUninterruptibly(); | |
r2.run(); | |
s1.release(); | |
} | |
} | |
; | |
} | |
.start(); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import java.util.concurrent.Semaphore; | |
// Don't do this ! | |
public class SingleSemaphoreHack { | |
private static void randomSleep(String threadId) { | |
int msecs = (int)(Math.random() * 1000); | |
System.out.println(String.format("%s going to sleep", threadId)); | |
try { | |
Thread.sleep(msecs); | |
} catch (InterruptedException e) {} | |
} | |
public static void main(String[] args) { | |
final Semaphore sem = new Semaphore(0); | |
Thread t1 = new Thread() { | |
int index = 0; | |
@Override | |
public void run() { | |
while(true) { | |
sem.acquireUninterruptibly(index); | |
randomSleep("main"); | |
sem.release(index+1); | |
index += 2; | |
} | |
} | |
}; | |
Thread t2 = new Thread() { | |
int index = 1; | |
@Override | |
public void run() { | |
while(true) { | |
sem.acquireUninterruptibly(index); | |
randomSleep("secondary"); | |
sem.release(index+1); | |
index += 2; | |
} | |
} | |
}; | |
t2.start(); | |
t1.start(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment