Thread waiting to multiple threads - java

I have to create a hedge simulator. There is eg. 10 segments of it and each of them should have its own dedicated Thread simulating grow of the segment (each time we're about to calculate whether segment growed up, we should perform random test).
In addition there should be one additional, gardener Thread.
Gardener should cut segment of hence, when its size reaches 10 (then he cuts its size back to initial level of 1 and adds notifies it in his notes).
My attempt to make it working was like this:
public class Segment implements Runnable {
private int currentSize;
#Override
public void run() {
if(Math.random() < 0.3)
incrementSize();
}
private synchronized void incrementSize() {
currentSize++;
}
public synchronized int getCurrentSize() {
return currentSize;
}
public synchronized void setCurrentSize(int newSize) {
currentSize = newSize;
}
}
public class Gardener implements Runnable {
private int[] segmentsCutAmount = new int[10]; //Gardener notes
private Collection<Segment> segments;
public Gardener(Collection<Segment> segmentsToLookAfter) {
segments = segmentsToLookAfter;
}
#Override
public void run() {
while(true) {
//Have no idea how to deal with 10 different segments here
}
}
}
public class Main {
private Collection<Segment> segments = new ArrayList<>():
public void main(String[] args) {
Main program = new Main();
for(int i = 0; i < 10; i++)
program.addSegment();
Thread gardenerThread = new Thread(new Gardener(program.segments));
}
private void addSegment(Collection<Segment> segments) {
Segment segment = new Segment();
Thread segmentThread = new Thread(segment);
segmentThread.start();
segments.add(segment);
}
}
I am not sure what am I supposed to do, when segment reaches max height.
If there was 10 gardeners, every of them could observe one segment, but, unfortunelly, gardener is a lonely shooter - he has no family and his friends are very busy and are not willing to help him. And are you willing to help me? :D
I generally know basics of synchronization - synchronized methods/blocks, Locks, wait and notify methods, but this time I have totally no idea what to do :(
Its like horrible deadlock! Of course I am not expecting to be spoonfeeded. Any kind of hint would be very helpful as well. Thank you in advance and have a wonderful day!

About that queue. You can use the ExecutorService for that.
Letting the Hedge grow
So let's you have a hedge that can grow and be cut.
class Hedge {
private AtomicInteger height = new AtomicInteger(1);
public int grow() {
return height.incrementAndGet();
}
public int cut() {
return height.decrementAndGet();
}
}
And then you have an environment that will let the hedge grow. This will simulate the hedge sections; each environment is responsible for one of the sections only. It will also notify a Consumer<Integer> when the hedge size has gone.
class SectionGrower implements Runnable {
public static final Random RANDOM = new Random();
private final Hedge hedge;
private final Consumer<Integer> hedgeSizeListener;
public SectionGrower (Hedge h, Consumer<Integer> hl) {
hedge = h;
hedgeSizeListener = hl
}
public void run() {
while (true) { // grow forever
try {
// growing the hedge takes up to 20 seconds
Thread.sleep(RANDOM.nextInt(20)*1000);
int sectionHeight = hedge.grow();
hedgeSizeListener.accept(sectionHeight);
} catch (Exception e) {} // do something here
}
}
}
So at this point, you can do this.
ExecutorService growingExecutor = Executors.newFixedThreadPool(10);
Consumer<Integer> printer = i -> System.out.printf("hedge section has grown to %d\n", i.intValue());
for (int i = 0; i < 10; i++) {
Hedge section = new Hedge();
Environment grower = new SectionGrower(section, printer);
growingExecutor.submit(grower::run);
}
This will grow 10 hedge sections and print the current height for each as they grow.
Adding the Gardener
So now you need a Gardener that can cut the hedge.
class Gardener {
public static final Random RANDOM = new Random();
public void cutHedge(Hedge h) {
try {
// cutting the hedge takes up to 10 seconds
Thread.sleep(RANDOM.nextInt(10)*1000);
h.cut();
} catch (Exception e) {} // do something here
}
}
Now you need some construct to give him work; this is where the BlockingQueue comes in. We've already made sure the Environment can notify a Consumer<Integer> after a section has grown, so that's what we can use.
ExecutorService growingExecutor = Executors.newFixedThreadPool(10);
// so this is the queue
ExecutorService gardenerExecutor = Executors.newSingleThreadPool();
Gardener gardener = new Gardener();
for (int i = 0; i < 10; i++) {
Hedge section = new Hedge();
Consumer<Integer> cutSectionIfNeeded = i -> {
if (i > 8) { // size exceeded?
// have the gardener cut the section, ie adding item to queue
gardenerExecutor.submit(() -> gardener.cutHedge(section));
}
};
SectionGrower grower = new SectionGrower(section, cutSectionIfNeeded);
growingExecutor.submit(grower::run);
}
So I haven't actually tried this but it should work with some minor adjustments.
Note that I use the AtomicInteger in the hedge because it might grow and get cut "at the same time", because that happens in different threads.

The in following code Gardner waits for Segment to get to an arbitrary value of 9.
When Segment gets to 9, it notifies Gardner, and waits for Gardner to finish trimming:
import java.util.ArrayList;
import java.util.Collection;
public class Gardening {
public static void main(String[] args) {
Collection<Segment> segments = new ArrayList<>();
for(int i = 0; i < 2; i++) {
addSegment(segments);
}
Thread gardenerThread = new Thread(new Gardener(segments));
gardenerThread.start();
}
private static void addSegment(Collection<Segment> segments) {
Segment segment = new Segment();
Thread segmentThread = new Thread(segment);
segmentThread.start();
segments.add(segment);
}
}
class Gardener implements Runnable {
private Collection<Segment> segments;
private boolean isStop = false; //add stop flag
public Gardener(Collection<Segment> segmentsToLookAfter) {
segments = segmentsToLookAfter;
}
#Override
public void run() {
for (Segment segment : segments) {
follow(segment);
}
}
private void follow(Segment segment) {
new Thread(() -> {
Thread t = new Thread(segment);
t.start();
synchronized (segment) {
while(! isStop) {
try {
segment.wait(); //wait for segment
} catch (InterruptedException ex) { ex.printStackTrace();}
System.out.println("Trimming Segment " + segment.getId()+" size: "
+ segment.getCurrentSize() ); //add size to notes
segment.setCurrentSize(0); //trim size
segment.notify(); //notify so segment continues
}
}
}).start();
}
}
class Segment implements Runnable {
private int currentSize;
private boolean isStop = false; //add stop flag
private static int segmentIdCounter = 0;
private int segmentId = segmentIdCounter++; //add an id to identify thread
#Override
public void run() {
synchronized (this) {
while ( ! isStop ) {
if(Math.random() < 0.0000001) {
incrementSize();
}
if(getCurrentSize() >= 9) {
notify(); //notify so trimming starts
try {
wait(); //wait for gardener to finish
} catch (InterruptedException ex) {
ex.printStackTrace();
}
}
}
}
}
private synchronized void incrementSize() {
currentSize++;
System.out.println("Segment " + getId()+" size: "
+ getCurrentSize() );
}
public synchronized int getCurrentSize() { return currentSize; }
public synchronized void setCurrentSize(int newSize) {
currentSize = newSize;
}
public int getId() { return segmentId; }
}
The mutual waiting mechanizem can be implemented also with CountDownLatch.
Note that my experience with threads is limited. I hope other users comment and suggest improvements.

Related

Java multi threading when multiple threads updating same variable

This is the program
public class Thread2 implements Runnable {
private static int runTill = 10000;
private static int count = 0;
#Override
public void run() {
for(int i=0;i<runTill;i++) {
count++;
}
}
public static void main(String s[]) {
int iteration = 10;
for(int i = 0; i < iteration ;i++) {
Thread t = new Thread(new Thread2());
t.start();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Expected : "+(iteration * runTill));
System.out.println("Actual : "+count);
}
}
At the end I want count to be equal to (Expected : 100000). How can I achieve this?
A call to count++ is not atomic: it first has to load count, increment it and then store the new value in the variable. Without synchronization in place, threads will interleave during execution of this operation.
A simple way to get what you want is to use an AtomicInteger:
private static AtomicInteger count = new AtomicInteger();
#Override
public void run() {
for(int i=0;i<runTill;i++) {
count.incrementAndGet();
}
}
use "compare and set" instead of "increment and get"
private static AtomicInteger count = new AtomicInteger();
#Override
public void run() {
for(int i=0;i<runTill;i++) {
//note: another thread might reach this point at the same time when i is 9,999
// (especially if you have other codes running prior to the increment within the for loop)
// then count will be added 2x if you use incrementAndGet
boolean isSuccessful = count.compareAndSet(i, i+1);
if(!isSuccessful)
System.out.println("number is not increased (another thread already updated i)");
}
}
As the comments suggest, besides the need for synchronizing access (to count, became an AtomicInteger here), threads should be waited to complete using Thread.join(), instead of "guessing" their runtime:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
public class Thread2 implements Runnable {
private static int runTill = 10000;
private static AtomicInteger count = new AtomicInteger();
#Override
public void run() {
for (int i = 0; i < runTill; i++) {
count.incrementAndGet();
}
}
public static void main(String s[]) {
int iteration = 10;
List<Thread> threads = new ArrayList<Thread>();
for (int i = 0; i < iteration; i++) {
Thread t = new Thread(new Thread2());
threads.add(t);
t.start();
}
try {
for (Thread t : threads)
t.join();
} catch (InterruptedException ie) {
ie.printStackTrace();
}
System.out.println("Expected : " + (iteration * runTill));
System.out.println("Actual : " + count);
}
}

Java Multithreading two classes in main

I am very new to programming, and I am trying to write a Java program with the Timer and ChecksUserInput classes shown below. How do I get them to run at the same time in the main class?
I am also having issues with printing out the word length in ChecksUserInput.
main.java:
package application;
public class Main {
public static void main(String[] args) {
CreateBoard board = new CreateBoard();
board.run();
Timer timer = new Timer();
timer.run();
ChecksUserInput input = new ChecksUserInput();
input.run();
}
}
timer.java:
package application;
public class Timer {
private static void time() {
final int mili = 1000;
final int sec = 60;
final int oneMinute = (mili * sec);
System.out.println("Start 3 minute timer");
sleep(oneMinute * 2);
System.out.println("One minute remaining...");
sleep(oneMinute);
System.out.println("Time's up!");
}
private static void sleep(int sleepTime) {
try {
Thread.sleep(sleepTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
time();
}
}
checksuserinput.java:
package application;
import java.util.*;
public class ChecksUserInput {
private static String UserInput() {
Scanner sc = new Scanner(System.in);
System.out.println("Begin entering words!");
String word = null;
for (int i = 0; i < 10000; i++) {
word = sc.nextLine();
}
return word;
}
private static int length(String word) {
int wordLength = word.length();
return wordLength;
}
public void run() {
String userWord = UserInput();
int wordLength = length(userWord);
System.out.println(wordLength);
}
}
The foundation of multi-threading in Java is the Thread class. The general structure for usage is:
Thread newProcess = new Thread(processToRun); //Create a thread which will execute the process
newProcess.setDaemon(true/false); //when false, the thread will keep the JVM alive beyond completion of 'main'
newProcess.start(); //Start processToRun in a new thread
To start several independent processes, this should be sufficient. For example, the following starts 10 threads each of which will print the index in the loop. At the end, the process sleeps for 5 milliseconds because the spawned threads are daemon. Removing this may cause the process to terminate before any messages are printed.
public static void main(String args[]) throws Exception
{
for(int i = 0; i < 10; i++) { int index = i; start(() -> System.out.println(index)); }
Thread.sleep(5);
}
public static void start(Runnable processToRun)
{
Thread newProcess = new Thread(processToRun);
newProcess.setDaemon(true);
newProcess.start();
}
Beyond this point questions start to get more complicated/contextual. Ex:
How can processes running in 2 threads communicate with each other?
How can processes running in 2 threads access/modify common state between them?
In the context of creating a simple game, one option is to use Queues to feed user inputs to the game and have the game process updates in a single thread. The following sample listens for the user inputting commands (Up, Down, Left, Right) on the main thread and adds valid commands to a queue. Valid commands are polled and processed in a different thread to update the location on the board.
Sample:
public static void main(String args[])
{
Board board = new Board();
BlockingQueue<Move> movesQueue = new ArrayBlockingQueue<>(100);
Scanner systemListener = new Scanner(System.in);
start(() -> routeBoardMovesToQueue(board, movesQueue)); /*route moves from the queue to the board in a new thread*/
while(true)
{
Optional<Move> nextMove = Move.resolve(systemListener.nextLine());
if(nextMove.isPresent())
movesQueue.offer(nextMove.get()); /*Write moves from System.in to the queue*/
else
System.out.println("Invalid Move Provided");
}
}
public static void routeBoardMovesToQueue(Board board, BlockingQueue<Move> movesQueue)
{
try
{
while(true)
{
Move next = movesQueue.poll(100_000, TimeUnit.DAYS);
if(next != null) board.performMove(next);
}
}
catch(InterruptedException ignored){ System.out.println("Stopping"); }
}
public static void start(Runnable processToRun)
{
Thread newProcess = new Thread(processToRun);
newProcess.setDaemon(true);
newProcess.start();
}
public static final class Board
{
private final Location location;
public Board(){ this.location = new Location(); }
public void performMove(Move move)
{
switch(move)
{
case Up: location.y += 1; break;
case Down: location.y -= 1; break;
case Right: location.x += 1; break;
case Left: location.x -= 1; break;
}
System.out.println("New Position: (" + location.x + ", " + location.y + ")");
}
public static class Location{ int x = 0; int y = 0; }
}
public enum Move
{
Up, Down, Left, Right;
public static Optional<Move> resolve(String move){ return Stream.of(Move.values()).filter(mv -> Objects.equals(move, mv.name())).findAny(); }
}
You should search "java multithreading" on your favourite search engine and compare your code with those examples
You will find that these people have (mostly) implemented the Runnable interface on their classes.
So
-- public class ChecksUserInput {
++ public class ChecksUserInput implements Runnable{
And run() was a method of that interface, that they had to implement.
Your version first runs the run method of the first class, then the other.
But when you implement the runnable interface, the both run methods will be called right after one another, without waiting for the first one to finish
You should search on your own and find more examples, or check the documentations for multithreading if you face any other issues
So after the wonderful help #BATIKAN BORA ORMANCI and #mike1234569 gave me along with this link https://www.geeksforgeeks.org/multithreading-in-java/ I was able to actually figure it out
package application;
public class Main {
public static void main(String[] args) {
CreateBoard board = new CreateBoard();
board.run();
Thread timer = new Thread(new Timer());
Thread input = new Thread(new ChecksUserInput());
timer.start();
input.start();
try {
timer.join();
input.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
and I set my classes to implement Runnable as Batikan suggested

Java Multithreading Semaphore

If I launch for example five threads in main class that will be running parralell
final int TERMINAL_COUNT = 5;
Semaphore semaphore = new Semaphore(1);
Queue<Terminal> terminals = new LinkedList<>();
for (int i = 1; i<= TERMINAL_COUNT; i++){
terminals.offer(new Terminal(i, semaphore));
}
for(Terminal terminal : terminals) terminal.start();
}
And class that carries them looks like
public class Terminal extends Thread {
private Dispetcher dispetcher;
private Semaphore semaphore;
public Terminal(int terminalId, Semaphore semaphore){
dispetcher = new Dispetcher();
this.semaphore = semaphore;
}
#Override
public void run() {
try{
ListIterator<Plane> pIt = dispetcher.getPlanes().listIterator();
while (pIt.hasNext()){
Plane p = pIt.next();
if(!p.isArrived()) {
//some code
replacingPassangers(p);
}
}
}catch (InterruptedException e){
e.printStackTrace();
}
}
private void replacingPassangers(Plane p) throws InterruptedException{
semaphore.acquire();
if(!p.isArrived()) {
//replacing passangers
p.setIsArrived(true);
}
semaphore.release();
}
}
So i need that after passengers is replaced by 1 thread the others skip methods logic with help of if(!p.isArriving) condition. But p.setIsArrived(true); doesn't affects this variable in other threads and as result all threads passing this condition... How can I fix it?

WaterTank ProducerConsumer Pattern

this is an exercise where i have 1 Producer and N Consumer ( fill and remove Water into an WaterTank ) which i implemented in the shown code.
Now the text of the exercise says:
Filling an additional tank:
This way u can be sure that water won't be put in and taken away at the same time.
Or you could as well say that water can only be taken away if there is a putOperation.
I don't understand it. I have synchronized on an private final object so the first part ( won't be put and taken away at the same time ) doesn't happen anyway. Also there is no need for an additional Watertank that way.
The second part where it will be taken at the same time it will be put i also quite don't understand. Do i need Semaphores or Reeantrantlock or anything?
I know i have to put an WaterTank Object into my already existing WaterTank as far as i understand.
Thy for any help :)
public class WaterTank {
private final int capacity;
private int water;
private final Object synchobj = new Object();
public WaterTank(int capacit, int wate) {
this.capacity = capacit;
this.water = wate;
}
public void fillwater(int wata) {
synchronized (synchobj) {
if (water + wata > capacity) {
System.out.println("Cannot fill water!");
} else {
water = water + wata;
System.out.println("FILL::::Capacity: " + capacity + " and Water: " + water);
}
}
}
public void removewater(int wata) {
synchronized (synchobj) {
if (water - wata < 0) {
System.out.println("Cannot take water!");
} else {
water = water - wata;
System.out.println("REMOVE:::Capacity: " + capacity + " and Water: " + water);
}
}
}
}
public class Producer implements Runnable {
private final WaterTank T;
public Producer(WaterTank t) {
this.T = t;
}
#Override
public void run() {
while (true) {
T.fillwater(10);
}
}
}
public class Consumer implements Runnable {
private final WaterTank T;
public Consumer(WaterTank t) {
this.T = t;
}
#Override
public void run() {
while (true) {
T.removewater(10);
}
}
}
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class test {
public static void main(String[] args) {
WaterTank F = new WaterTank(100, 0);
Thread Pro = new Thread(new Producer(F));
Pro.start();
ExecutorService exec = Executors.newCachedThreadPool();
for (int i = 0; i < 5; i++) {
exec.execute(new Consumer(F));
}
}
}

Ordering threads to run in the order they were created/started

How can i order threads in the order they were instantiated.e.g. how can i make the below program print the numbers 1...10 in order.
public class ThreadOrdering {
public static void main(String[] args) {
class MyRunnable implements Runnable{
private final int threadnumber;
MyRunnable(int threadnumber){
this.threadnumber = threadnumber;
}
public void run() {
System.out.println(threadnumber);
}
}
for(int i=1; i<=10; i++){
new Thread(new MyRunnable(i)).start();
}
}
}
Sounds like you want ExecutorService.invokeAll, which will return results from worker threads in a fixed order, even though they may be scheduled in arbitrary order:
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class ThreadOrdering {
static int NUM_THREADS = 10;
public static void main(String[] args) {
ExecutorService exec = Executors.newFixedThreadPool(NUM_THREADS);
class MyCallable implements Callable<Integer> {
private final int threadnumber;
MyCallable(int threadnumber){
this.threadnumber = threadnumber;
}
public Integer call() {
System.out.println("Running thread #" + threadnumber);
return threadnumber;
}
}
List<Callable<Integer>> callables =
new ArrayList<Callable<Integer>>();
for(int i=1; i<=NUM_THREADS; i++) {
callables.add(new MyCallable(i));
}
try {
List<Future<Integer>> results =
exec.invokeAll(callables);
for(Future<Integer> result: results) {
System.out.println("Got result of thread #" + result.get());
}
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (ExecutionException ex) {
ex.printStackTrace();
} finally {
exec.shutdownNow();
}
}
}
"I actually have some parts that i want to execute in parallel, and then once the results are generated, I want to merge the results in certain order." Thanks, this clarifies what you're asking.
You can run them all at once, but the important thing is to get their results in order when the threads finish their computation. Either Thread#join() them in the order in which you want to get their results, or just Thread#join() them all and then iterate through them to get their results.
// Joins the threads back to the main thread in the order we want their results.
public class ThreadOrdering {
private class MyWorker extends Thread {
final int input;
int result;
MyWorker(final int input) {
this.input = input;
}
#Override
public void run() {
this.result = input; // Or some other computation.
}
int getResult() { return result; }
}
public static void main(String[] args) throws InterruptedException {
MyWorker[] workers = new MyWorker[10];
for(int i=1; i<=10; i++) {
workers[i] = new MyWorker(i);
workers[i].start();
}
// Assume it may take a while to do the real computation in the threads.
for (MyWorker worker : workers) {
// This can throw InterruptedException, but we're just passing that.
worker.join();
System.out.println(worker.getResult());
}
}
}
Simply put, the scheduling of threads is indeterminate.
http://www.janeg.ca/scjp/threads/scheduling.html Dead domain - do not click
WaybackMachine version of the above page
The longer answer is that if you want to do this, you'll need to manually wait for each thread to complete its work before you allow another to run. Note that in this fashion, all the threads will still interleave but they won't accomplish any work until you give the go-ahead. Have a look at the synchronize reserved word.
You can chain them – that is, have the first one start the second, the second start the third, etc. They won't really be running at the same time except for a bit of overlap when each one is started.
public class ThreadOrdering
{
public static void main(String[] args)
{
MyRunnable[] threads = new MyRunnable[10];//index 0 represents thread 1;
for(int i=1; i<=10; i++)
threads[i] = new MyRunnable(i, threads);
new Thread(threads[0].start);
}
}
public class MyRunnable extends Runnable
{
int threadNumber;
MyRunnable[] threads;
public MyRunnable(int threadNumber, MyRunnable[] threads)
{
this.threadnumber = threadnumber;
this.threads = threads;
}
public void run()
{
System.out.println(threadnumber);
if(threadnumber!=10)
new Thread(threadnumber).start();
}
}
Here's a way to do it without having a master thread that waits for each result. Instead, have the worker threads share an object which orders the results.
import java.util.*;
public class OrderThreads {
public static void main(String... args) {
Results results = new Results();
new Thread(new Task(0, "red", results)).start();
new Thread(new Task(1, "orange", results)).start();
new Thread(new Task(2, "yellow", results)).start();
new Thread(new Task(3, "green", results)).start();
new Thread(new Task(4, "blue", results)).start();
new Thread(new Task(5, "indigo", results)).start();
new Thread(new Task(6, "violet", results)).start();
}
}
class Results {
private List<String> results = new ArrayList<String>();
private int i = 0;
public synchronized void submit(int order, String result) {
while (results.size() <= order) results.add(null);
results.set(order, result);
while ((i < results.size()) && (results.get(i) != null)) {
System.out.println("result delivered: " + i + " " + results.get(i));
++i;
}
}
}
class Task implements Runnable {
private final int order;
private final String result;
private final Results results;
public Task(int order, String result, Results results) {
this.order = order;
this.result = result;
this.results = results;
}
public void run() {
try {
Thread.sleep(Math.abs(result.hashCode() % 1000)); // simulate a long-running computation
}
catch (InterruptedException e) {} // you'd want to think about what to do if interrupted
System.out.println("task finished: " + order + " " + result);
results.submit(order, result);
}
}
If you need that fine-grained control, you should not use threads but instead look into using a suitable Executor with Callables or Runnables. See the Executors class for a wide selection.
A simple solution would be to use an array A of locks (one lock per thread). When thread i begins its executions, it acquires its associated lock A[i]. When it's ready to merge its results, it releases its lock A[i] and waits for locks A[0], A[1], ..., A[i - 1] to be released; then it merges the results.
(In this context, thread i means the i-th launched thread)
I don't know what classes to use in Java, but it must be easy to implement. You can begin reading this.
If you have more questions, feel free to ask.
public static void main(String[] args) throws InterruptedException{
MyRunnable r = new MyRunnable();
Thread t1 = new Thread(r,"A");
Thread t2 = new Thread(r,"B");
Thread t3 = new Thread(r,"C");
t1.start();
Thread.sleep(1000);
t2.start();
Thread.sleep(1000);
t3.start();
}
Control of thread execution order may be implemented quite easily with the semaphores. The code attached is based on the ideas presented in Schildt's book on Java (The complete reference....).
// Based on the ideas presented in:
// Schildt H.: Java.The.Complete.Reference.9th.Edition.
import java.util.concurrent.Semaphore;
class Manager {
int n;
// Initially red on semaphores 2&3; green semaphore 1.
static Semaphore SemFirst = new Semaphore(1);
static Semaphore SemSecond = new Semaphore(0);
static Semaphore SemThird = new Semaphore(0);
void firstAction () {
try {
SemFirst.acquire();
} catch(InterruptedException e) {
System.out.println("Exception InterruptedException catched");
}
System.out.println("First: " );
System.out.println("-----> 111");
SemSecond.release();
}
void secondAction() {
try{
SemSecond.acquire();
} catch(InterruptedException e) {
System.out.println("Exception InterruptedException catched");
}
System.out.println("Second: ");
System.out.println("-----> 222");
SemThird.release();
}
void thirdAction() {
try{
SemThird.acquire();
} catch(InterruptedException e) {
System.out.println("Exception InterruptedException catched");
}
System.out.println("Third: ");
System.out.println("-----> 333");
SemFirst.release();
}
}
class Thread1 implements Runnable {
Manager q;
Thread1(Manager q) {
this.q = q;
new Thread(this, "Thread1").start();
}
public void run() {
q.firstAction();
}
}
class Thread2 implements Runnable {
Manager q;
Thread2(Manager q) {
this.q = q;
new Thread(this, "Thread2").start();
}
public void run() {
q.secondAction();
}
}
class Thread3 implements Runnable {
Manager q;
Thread3(Manager q) {
this.q = q;
new Thread(this, "Thread3").start();
}
public void run() {
q.thirdAction();
}
}
class ThreadOrder {
public static void main(String args[]) {
Manager q = new Manager();
new Thread3(q);
new Thread2(q);
new Thread1(q);
}
}
This can be done without using synchronized keyword and with the help of volatile keyword. Following is the code.
package threadOrderingVolatile;
public class Solution {
static volatile int counter = 0;
static int print = 1;
static char c = 'A';
public static void main(String[] args) {
// TODO Auto-generated method stub
Thread[] ths = new Thread[4];
for (int i = 0; i < ths.length; i++) {
ths[i] = new Thread(new MyRunnable(i, ths.length));
ths[i].start();
}
}
static class MyRunnable implements Runnable {
final int thID;
final int total;
public MyRunnable(int id, int total) {
thID = id;
this.total = total;
}
#Override
public void run() {
while(true) {
if (thID == (counter%total)) {
System.out.println("thread " + thID + " prints " + c);
if(c=='Z'){
c='A';
}else{
c=(char)((int)c+1);
}
System.out.println("thread " + thID + " prints " + print++);
counter++;
} else {
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// log it
}
}
}
}
}
}
Following is the github link which has a readme, that gives detailed explanation about how it happens.
https://github.com/sankar4git/volatile_thread_ordering

Categories