Thread needs to wait a list is updated - java

The class below updates a map in particluar interval of time.
public class CheckerThread extends Thread {
private volatile HashMap<String, Integer> map = new HashMap<>();
#Override
public void run() {
while (true) {
updateMap();
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
// Do something
}
}
}
private void updateMap() {
HashMap<String, Integer> localMap = new HashMap<>();
int count = 0;
while (count < 10) {
localMap.put(count + "a", count);
count++;
}
this.map = localMap;
}
public Map<String, Integer> getMap() {
return this.map;
}
}
The Class below calls the method getMap() to get the Map . I need to ensure the list is fully updated before returning the map in the class "CheckerThread". The method should wait till map is updated.
public class GetterThread extends Thread {
private final CheckerThread checkerThread;
public GetterThread(final CheckerThread checkerThread) {
this.checkerThread = checkerThread;
}
#Override
public void run() {
System.err.println(this.checkerThread.getMap());
}
}
Another class Main creates threads.
public class MainThread extends Thread {
public static void main(final String[] args) throws InterruptedException {
int i = 0;
GetterThread[] getterThreads = new GetterThread[5];
CheckerThread checkerThread = new CheckerThread();
checkerThread.start();
while (i < 5) {
getterThreads[i] = new GetterThread(checkerThread);
getterThreads[i].start();
Thread.sleep(1000);
i++;
}
}
}
}

The idea of a threading is ok for that but not enough (most of them because threads don't return anything after they do the job...) if you want to still work with threads then you will end in a wait/join/notify approach...
you can instead of a thread --> runnable use a task --> callable,
Callables are threads on steroids, you can execute them in a ExecutorService and wait until the job is done getting even a result that let you know if everything went ok or not!!
take this as an example and consult the doc for more information:
ExecutorService
FutureTask
Callabel
public class _Foo {
public static void main(String... args) throws InterruptedException, ExecutionException {
ExecutorService exService = Executors.newSingleThreadExecutor();
FutureTask<Boolean> futureTask = new FutureTask<>(new MapCleaner());
exService.execute(futureTask);
System.out.println("Was everything ok??: " + futureTask.get());
}
}
class MapCleaner implements Callable<Boolean> {
#Override
public Boolean call() {
try {
Thread.sleep(3000);
} catch (InterruptedException ex) {
System.out.println(ex);
}
return System.currentTimeMillis() % 2 == 0;
}
}

Have you looked at Futures? Future.get() waits for task to get completed. Could this be what you need?
public class MyCallable implements Callable<Map<String, Integer>> {
private volatile HashMap<String, Integer> map = new HashMap<>();
private boolean wait = true;
public void call() {
while (wait) {
updateMap();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
}
}
return map;
}
private void updateMap() {
HashMap<String, Integer> localMap = new HashMap<>();
int count = 0;
while (count < 10) {
localMap.put(count + "a", count);
}
this.map = localMap;
wait = false;
}
}
and just call the future
ExecutorService executor = Executors.newSingleThreadExecutor();
Future<Map<String, Integer>> future = executor.submit(new MyCallable());
// Future.get() waits for task to get completed
Map<String, Integer> myMap = fut.get();

Based on your example, I think you should be using a BlockingQueue. Put elements into the queue in your "checker" thread, and read them with a blocking wait in the "getter" thread. This is easy and pretty clean, not too many changes are needed.
A queue will solve not only synchronization problems for you but also timing problems. No matter which order your threads run, your getter thread always waits until data is available, then returns. It's pretty much bomb proof.
BTW you have a bug in your checker thread. You put ten elements into the map, but you never increment count, so that loop never exits (it puts an infinite number of elements into the map, you'll get an out of memory error eventually).
Also, never ever catch and ignore InterruptedException. You almost always want to exit your thread if you get interrupted. C.f. Brian Goetz's book Java Concurrency in Practice for more.
public class SimpleThreading
{
public static void main(String[] args) throws InterruptedException {
MainThread.main(args);
}
}
class MainThread extends Thread
{
public static void main( final String[] args )
throws InterruptedException
{
int i = 0;
GetterThread[] getterThreads = new GetterThread[ 5 ];
CheckerThread checkerThread = new CheckerThread();
checkerThread.start();
while( i < 5 ) {
getterThreads[i] = new GetterThread( checkerThread );
getterThreads[i].start();
Thread.sleep( 1000 );
i++;
}
}
}
class GetterThread extends Thread
{
private final CheckerThread checkerThread;
public GetterThread( final CheckerThread checkerThread )
{
this.checkerThread = checkerThread;
}
#Override
public void run()
{
try {
System.out.println("waiting..." + checkerThread.getQueue() );
System.err.println( this.checkerThread.getQueue().take() );
} catch( InterruptedException ex ) {
// exit on interrupt
}
}
}
class CheckerThread extends Thread
{
private HashMap<String, Integer> map;
private final BlockingQueue<Map<String,Integer>> queue =
new LinkedBlockingQueue<>();
#Override
public void run()
{
while( true )
try {
updateMap();
queue.put( map );
System.out.println( "Added " + map );
Thread.sleep( 1000 );
} catch( InterruptedException e ) {
return; // exit on interrupt
}
}
private void updateMap()
{
HashMap<String, Integer> localMap = new HashMap<>();
int count = 0;
while( count < 10 )
localMap.put( count + "a", count++ );
this.map = localMap;
}
public BlockingQueue<Map<String, Integer>> getQueue()
{
return queue;
}
}

Related

Thread.sleep doesn't force context switch apparently

Main thread creates child thread. Parent needs some work from child, but not all of it, so parent must wait until child finish that work (child will keep doing some other work).
I would like to achieve it with monitors so I coded the following:
public class WaitChildThreadMonitor {
public static final int TOTAL_COUNT_AMOUNT = 1_000;
static int count = 0;
class Child implements Runnable {
#Override
public void run() {
work();
}
public synchronized void work() {
letParentWaitForThis();
for (int i = 0; i < TOTAL_COUNT_AMOUNT; i++)
++WaitChildThreadMonitor.count;
this.notifyAll();
// More child work that parent doesn't need right now
// ...
for (int i = 0; i < TOTAL_COUNT_AMOUNT; i++)
++WaitChildThreadMonitor.count;
}
private void letParentWaitForThis() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {}
}
public synchronized void waitForWork() throws InterruptedException {
this.wait();
}
}
void main() throws InterruptedException {
Child child = new Child();
Thread childThread = new Thread(child);
// If the next two methods doesn't execute atomically,
// parent execution gets blocked forever
childThread.start();
child.waitForWork();
System.out.printf("Count value is %d\n", WaitChildThreadMonitor.count);
childThread.join();
}
public static void main(String[] args) throws InterruptedException {
(new WaitChildThreadMonitor()).main();
}
}
The problem is that if child executes "this.notifyAll()" after he finished his main work before parent executes "this.wait()" in "child.waitForWork()", parent won't get notified and will get blocked forever.
I tried to solve it forcing a context switch before child start his work using Thread.sleep() method. It doesn't seem to work as expected.
With sleep and without sleep, sometimes parent gets blocked and program never ends, sometimes it ends properly (I guess because parent waited before child notified).
How can I fix this?
Thanks in advance!
You must not call wait if the thing you want to wait for has already happened. That's the reason the method that calls wait is synchronized -- so you can check the shared state that represents the thing you're waiting for.
So this is a standard producer-consumer problem. A long time ago, I wrote an implementation using only synchronized and wait-notify. I don't see what your code produces; this code just uses int as the thing produced. Change the type of the array inside Storage for some other class type.
package quicktest;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
*
* #author Brenden Towey
*/
public class ProducerConsumer {
public static void main(String[] args) throws InterruptedException {
Storage circularBuffer = new Storage();
Counter producer1 = new Counter( circularBuffer, 1000 );
Counter producer2 = new Counter( circularBuffer, 2000 );
Counter producer3 = new Counter( circularBuffer, 3000 );
Counter producer4 = new Counter( circularBuffer, 4000 );
ExecutorService exe = Executors.newCachedThreadPool();
exe.execute( producer1 );
exe.execute( producer2 );
exe.execute( producer3 );
exe.execute( producer4 );
Printer consumer = new Printer( circularBuffer );
exe.execute( consumer );
Thread.sleep( 100 );// wait a bit
exe.shutdownNow();
exe.awaitTermination( 10, TimeUnit.SECONDS );
}
}
// Producer
class Counter implements Runnable {
private final Storage output;
private final int startingValue;
public Counter(Storage output, int startingValue) {
this.output = output;
this.startingValue = startingValue;
}
#Override
public void run() {
try {
for( int i = startingValue; ; i++ )
output.put(i);
} catch (InterruptedException ex) {
// exit...
}
}
}
class Storage {
private final int[] buffer = new int[20];
private int head;
private int count;
public synchronized void put( int i ) throws InterruptedException {
while( count == buffer.length ) wait();// full
buffer[head++] = i;
head %= buffer.length;
count++;
notifyAll();
}
public synchronized int get() throws InterruptedException {
while( count == 0 ) wait(); // empty
int tail = (head - count) % buffer.length;
tail = (tail < 0) ? tail + buffer.length : tail;
int retval = buffer[tail];
count--;
notifyAll();
return retval;
}
}
// Consumer
class Printer implements Runnable {
private final Storage input;
public Printer(Storage input) {
this.input = input;
}
#Override
public void run() {
try {
for( ;; )
System.out.println( input.get() );
} catch (InterruptedException ex) {
// exit...
}
}
}

synchronizing a resource in executor framework

I am using executor framework for carrying out a large task. I need to keep a count of how many have been completed for process status purpose. So i have created a singleton class with a counter to keep the count.
public class ProgramInitializationTracker {
private static Map<String, Integer> programInitializedTracker = new HashMap<>();
private static ProgramInitializationTracker instance;
private ProgramInitializationTracker(){
}
public static ProgramInitializationTracker getInstance(){
if(instance == null){
synchronized (ProgramInitializationTracker.class) {
if(instance == null){
instance = new ProgramInitializationTracker();
}
}
}
return instance;
}
public Integer getProgramInitializedTracker(String key) {
return programInitializedTracker.get(key);
}
public void setProgramInitializedTracker(String key, int value) {
synchronized (ProgramInitializationTracker.class) {
ProgramInitializationTracker.programInitializedTracker.put(key, value);
}
}
}
But the problem is only by synchronizing set method will not really ensure that i have correct value of count. As far as i could get multithreading. Do making get function also synchronized will help me. If no then what should i have done to make it correct.
You should not attempt to implement your own thread-safe access to a collection when Java already provides this for you.
You should use a ConcurrentHashMap. Reads such as get do not block.
But rather than use an Integer type as the value stored in the map, you should use an AtomicInteger, which will ensure that multiple threads attempting to modify the value associated with the same key will be thread safe.
Under constraints you posted, simply sharing an instance of AtomicInteger between tasks you submit to an ExecutorService and a place you want to have a metric must do. variant1 is for having single counter covering all tasks and variant2 is for having counter per task type. This code is (should be) thread-safe.
#ThreadSafe
class Test {
private static class CountingRunnable implements Runnable {
#Nonnull
private final Runnable actualTask;
#Nonnull
private final AtomicInteger submitted;
public CountingRunnable(#Nonnull Runnable actualTask, #Nonnull AtomicInteger submitted) {
this.actualTask = actualTask;
this.submitted = submitted;
}
#Override
public void run() {
actualTask.run();
submitted.incrementAndGet();
}
}
public static void main(String[] args) throws InterruptedException {
variant2();
}
private static void variant1() throws InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(2);
AtomicInteger counter = new AtomicInteger();
final CountDownLatch latch = new CountDownLatch(1);
service.submit(new CountingRunnable(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
latch.countDown();
} catch (InterruptedException e) {}
}
}, counter));
latch.await();
System.out.println(counter.get());
service.shutdown();
}
private enum TaskType {
TYPE_1,
TYPE_2
}
private static void variant2() throws InterruptedException {
ExecutorService service = Executors.newFixedThreadPool(2);
final CountDownLatch latch = new CountDownLatch(2);
final EnumMap<TaskType, AtomicInteger> metrics = new EnumMap<>(TaskType.class);
metrics.put(TaskType.TYPE_1, new AtomicInteger());
metrics.put(TaskType.TYPE_2, new AtomicInteger());
service.submit(new CountingRunnable(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, metrics.get(TaskType.TYPE_1)));
service.submit(new CountingRunnable(new Runnable() {
#Override
public void run() {
try {
Thread.sleep(1000);
latch.countDown();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}, metrics.get(TaskType.TYPE_2)));
latch.await();
System.out.println("type 1: " + metrics.get(TaskType.TYPE_1));
System.out.println("type 2: " + metrics.get(TaskType.TYPE_2));
service.shutdown();
}
}

How to watch my Thread variable from Main class?

I have that code:
Main class:
public class myTest {
public static void main(String[] args) {
try {
Thread t1 = new myThreadClass("thread 1");
t1.start();
} catch (UnknownHostException ex) {
Logger.getLogger(glownyTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(glownyTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
My Thread class
public class myThreadClass extends Thread {
private HashSet<String> texts = new HashSet<String>();
public myThreadClass(String id) throws UnknownHostException, IOException {}
#Override
public void run() {
... collecting Strings into my hashSet ....
}
public HashSet<String> getTexts() {
return texts;
}
}
My Thread class is watching for network traffic, so I just cant call once
t1.getTexts()
whenever I want, because my hashSet can be empty (there are delays and latency in this network). How can I watch this texts hashSet and when some String will be added into hashSet - I i want my MAIN CLASS know about it? I just want to watch my Thread resources from Main class in smart way :)
If it will still be empty after my thread timeout, I want to know about it too.
You can use condition variables for this. Try something like:
class Monitor {
private final ConcurrentMap<String,String> data = new ConcurrentHashMap<String,String>();
private final Object mutex = new Object();
/* Private to the monitoring thread. Wakes up other
* threads, which may be waiting for data to arrive
*/
public void addElement(String key) {
data.put(key, key);
synchronized (mutex) { mutex.notifyAll(); }
}
public void removeElement(String key) {
data.remove(key);
synchronized (mutex) { mutex.notifyAll(); }
}
public Set<String> getElements() {
return data.keySet();
}
/* Can be called from any thread. Will wait at most "timeout"
* milliseconds
*/
public boolean waitForChanges(long timeout) throws InterruptedException {
final long then = System.currentTimeMillis() + timeout;
long left = timeout;
synchronized (mutex) {
while (data.isEmpty() && left > 0) {
mutex.wait(left);
left = then - System.currentTimeMillis();
}
return !data.isEmpty();
}
}
}
class MonitoringTask extends Runnable {
private final Monitor monitor;
MonitoringTask(Monitor m) {
this.monitor = m;
}
public void run() {
while (true) {
if (somethingHasHappened()) {
monitor.addElement("foo");
}
}
}
}
class Main {
public static void main(String[] args) {
final Monitor monitor = new Monitor();
final MonitoringTask task = new MonitoringTask(monitor);
final Thread thread = new Thread(task);
thread.setName("Monitor Thread");
thread.start();
if (monitor.waitForChanges(1500)) {
final Set<String> elts = monitor.getElements();
...
} else {
// Time-out
}
}
}
(I haven't tried to present this to a Java compiler, so watch out for all kinds of mistakes).

In Java Concurrency In Practice by Brian Goetz

Java Concurrency In Practice by Brian Goetz provides an example of a efficient scalable cache for concurrent use. Here is the code for the class:
public class Memoizer<A, V> implements Computable<A, V> {
private final ConcurrentMap<A, Future<V>> cache
= new ConcurrentHashMap<A, Future<V>>();
private final Computable<A, V> c;
public Memoizer(Computable<A, V> c) { this.c = c; }
public V compute(final A arg) throws InterruptedException {
while (true) {
Future<V> f = cache.get(arg);
if (f == null) {
Callable<V> eval = new Callable<V>() {
public V call() throws InterruptedException {
return c.compute(arg);
}
};
FutureTask<V> ft = new FutureTask<V>(eval);
f = cache.putIfAbsent(arg, ft);
if (f == null) { f = ft; ft.run(); }
}
try {
return f.get();
} catch (CancellationException e) {
cache.remove(arg, f);
} catch (ExecutionException e) {
throw launderThrowable(e.getCause());
}
}
} }
Probably a stupid question but coudl anyone show me the concurrent usage of this class?
Like in a main?
Cheers,
Agata
Here is an example which calculates factorials:
public static void main(String[] args) throws Exception {
//create a memoizer that performs factorials
final Memoizer<Integer, Integer> memo = new Memoizer<Integer, Integer> (new Computable<Integer, Integer>() {
#Override
public Integer compute(Integer a) {
int result = 1 ;
for(int i = 1 ; i < a ; i++){
result = result*i;
}
return result;
}
});
//now call the memoizer
System.out.println(memo.compute(10));
//call it with 10 threads concurrently
ExecutorService exec = Executors.newFixedThreadPool(10);
ExecutorCompletionService<Integer> compService = new ExecutorCompletionService<Integer>(exec);
for(int i = 0 ; i < 15 ; i++){
compService.submit(new Callable<Integer>(){
#Override
public Integer call() throws Exception {
return memo.compute(5);
}
});
}
exec.shutdown();
for(int i = 0 ; i < 15 ; i++){
System.out.println(compService.take().get());
}
}
So if two threads try to compute the same factorial at exactly the same time, only one of them will actually perform the computation, because putIfAbsent is threadsafe. The second thread will simply get the future which was put in the map by the first thread and wait for it to finish.
I could imagine something like this:
class PrimeDetector implements Computable<BigInteger, Boolean> {
public Boolean compute(BigInteger number) {
// detect whether the number is prime and return true if it is
}
}
Memoizer<BigInteger, Boolean> primeMemoizer =
new Memoizer<BigInteger, BigInteger[]>(new PrimeDetector());
boolean isPrime = primeMemoizer.compute(
new BigInteger("5625945193217348954671586615478165774647538956473535"));
...

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