Created
August 9, 2018 08:20
-
-
Save RustyKnight/da90e83d95ce795c963ab3a4f942a19b to your computer and use it in GitHub Desktop.
Demonstration of using two threads to synchronise the printing of odd and even lists of numbers, so they appear in order
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.locks.Condition; | |
import java.util.concurrent.locks.ReentrantLock; | |
import java.util.logging.Level; | |
import java.util.logging.Logger; | |
public class Test { | |
public static void main(String[] args) throws InterruptedException { | |
ReentrantLock lock = new ReentrantLock(); | |
Condition con = lock.newCondition(); | |
Thread t1 = new Thread(new Even(lock, con)); | |
Thread t2 = new Thread(new Odd(lock, con)); | |
t1.start(); | |
t2.start(); | |
Thread.sleep(5); | |
lock.lock(); | |
con.signalAll(); | |
lock.unlock(); | |
t1.join(); | |
t2.join(); | |
} | |
public static class Odd implements Runnable { | |
private ReentrantLock lock; | |
private Condition con; | |
public Odd(ReentrantLock lock, Condition con) { | |
this.lock = lock; | |
this.con = con; | |
} | |
@Override | |
public void run() { | |
try { | |
lock.lock(); | |
for (int num = 1; num < 10; num += 2) { | |
con.await(); | |
System.out.println(num); | |
con.signalAll(); | |
} | |
lock.unlock(); | |
} catch (InterruptedException ex) { | |
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
} | |
} | |
public static class Even implements Runnable { | |
private ReentrantLock lock; | |
private Condition con; | |
public Even(ReentrantLock lock, Condition con) { | |
this.lock = lock; | |
this.con = con; | |
} | |
@Override | |
public void run() { | |
try { | |
// The Odd thread MUST take the lock first, as it will wait for us | |
// to signal it after we've started | |
while (!lock.isLocked()) { | |
Thread.yield(); | |
} | |
lock.lock(); | |
for (int num = 0; num < 10; num += 2) { | |
System.out.println(num); | |
con.signalAll(); | |
con.await(); | |
} | |
lock.unlock(); | |
} catch (InterruptedException ex) { | |
Logger.getLogger(Test.class.getName()).log(Level.SEVERE, null, ex); | |
} | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
So, the following is a little messy, but it demonstrates a basic concept of "thread locking" use
ReentrantLock
s andCondition
sThere is a lot going on with threading, when a thread is scheduled to run is not up to you, it's up to the OS. We can, however, restrict when a
Thread
might be allowed to executed through the use of locks and conditions.Basically all this does it stops one thread from continuing while the other updates. When it's completed it will signal the other thread that it can run and then wait till it's completed, so and so forth.
The locking/condition is setup in such away in an attempt to let the threads run slightly differently from each other, otherwise it's might be possible to have the odd thread printing first
As I said, it's a little messy and there might be some better ways to approach it, but it provides a basic demonstration of "guarded blocks" using locks
Concurrency is a complex subject at the best of times and isn't going to be answered here, it's better if you take the time to read through the linked tutorial and experiment with it some more.