How to Synchronize Threads - java

In this multithreading program, when I run it, I always get the output in some random order. But I was wondering if there is any way I can make this program to work in synchronized mode. Like when I runt it then for the first thread it should print out everything, then for second thread it should print out something, then for third thread it should print out everything etc etc. So sample output should be like this for each thread-
Task 1 Started
original: Hello World
Difference:- 0
Task 1 Ended
Task 2 Started
original: Hello World
Difference:- 0
Task 2 Ended
............
............
Task 15 Started
original: Hello World
Difference:- 0
Task 15 Ended
This is my below program. Any suggestions will be appreciated.
class ThreadTask implements Runnable {
private int id;
public ThreadTask(int id) {
this.id = id;
}
public synchronized void run() {
System.out.println("Task " + id + " Started ");
String originalString = "Hello World";
System.out.println("original: " + originalString);
System.out.println("Task " + id + " Ended ");
}
}
public class TestPool {
public static void main(String[] args) throws InterruptedException {
int size = 5; //Integer.parseInt(args[0]);
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(size);
// queue some tasks
for(int i = 1; i <= 3 * size; i++) {
service.submit(new ThreadTask(i));
}
// wait for termination
service.shutdown();
service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}

You commented on Jakub's answer as follows:
Can you give me example basis on my code as I just started learning about threading. It will be of great help to me.
What Jakub is saying is that forcing threads to run in a fixed sequence defeats the purpose of using threads in the first place. Think about this.
If you really do want / need your example to run the tasks in order, you may as well do this:
for (int i = 1; i <= 3 * size; i++) {
new ThreadTask(i).run();
}
i.e. just run the runnables in the current thread.
Or you could set the maximum pool size to 1, which forces the service to run the tasks in order. (Of course, this defeats the point of using threads. You won't get any parallelism this way.)
A more sensible approach would be to have each thread return its results in a Future, and then have the main thread fetch the value from each future (in the required order) and print it. Basically, you want to allow the threads to run in any order (and in parallel, if you have multiple cores), but then impose the ordering when you access the results.

The essence of thread is that they can run simultaneously, if you want them to run in order, simply do not use Thread.
There's another kind of requirement, that maybe you want several jobs to work together (simultaneously), but in a given order. In this case, I highly suggest you to implement a queuing system. That is, build a queue like
Queue <C> q
And a thread
class T implements Runnable {
public void run() {
while (!q.empty()) {
// Do something
}
}
}
You can use Runnable through ExecutorService, like the code that you've used.
You can also add some elements into the queue in "Do something" section of previous code, then you can control the order of jobs by yourself.

You can save the the reference to the previous thread and hook up the next thread to the previous one using join(). That will ensure the threads will be run in a series (next one not starting unless the previous one finished). But the point of doing that is eluding me.
public class TestPool
{
static class ThreadTask extends Thread
{
private int id;
private Thread previous;
public ThreadTask(int id, Thread previous){
this.id = id;
this.previous = previous;
}
public void run(){
if(previous != null){
try{
previous.join();
}
catch(InterruptedException e){
e.printStackTrace();
}
}
System.out.println("Task " + id + " Started ");
String originalString = "Hello World";
System.out.println("original: " + originalString);
System.out.println("Task " + id + " Ended ");
}
}
public static void main(String[] args) throws InterruptedException{
int size = 5; // Integer.parseInt(args[0]);
// create thread pool with given size
ExecutorService service = Executors.newFixedThreadPool(size);
Thread previous = null;
// queue some tasks
for(int i = 1; i <= 3 * size; i++){
Thread thread = new ThreadTask(i, previous);
previous = thread;
thread.start();
//service.submit(thread);
}
// wait for termination
//service.shutdown();
//service.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
}
}
Not tested, sry. I don't also know what the ExecutorService is doing, it might break this. Note that I need to be a Thread, being Runnable is not enough. Also, run() needs not be synchronised, as it will be called only once per execution. And you should not start the threads with run(), but with start().
EDIT: I just tried to run it, and the ExecutorService is fu**ing things up. If you just start the thread (like the my code does), then it's working.

Related

Do these threads started from a loop execute asynchronously?

My data size is huge so I thought of dividing it into chunks and using threads to process it asynchronously.
To make it simple let's say I have a list and associate each entry with a thread, so the number of threads is equal to the number of elements. Since I am new to threads in Java so I am not sure how the threads run asynchronously. Here is a simplified code for better understanding.
class ThreadRunner extends Thread {
String threadName;
String element;
public MyThread (String threadName, String element) {
this.threadName = threadName;
this.element = element;
}
public void run() {
System.out.println("Run: "+ threadName);
// some processing on the item
}
}
class TestThread {
public static void main (String arg[]) {
List<String> mainList = new ArrayList<>();
for (int x=0; x< mainList.size(); x++)
{
MyThread temp= new MyThread("Thread #" + x+1);
temp.start();
System.out.println("Started Thread:" + x+1);
}
}
Does this code execute the threads in an asynchronous manner?
Instead of spawning threads yourself, use an ExecutorService and submit work to it in the form of Runnables.
Each Runnable task should process enough work to justify the overhead of spawning threads but not so much work that you underutilize the other cores. In other words, you want to properly load balance the work across your cores. One way to do this is to divide the elements evenly across the tasks so that each task processes roughly num_threads / mainList.size()elements and you submit num_thread tasks to the ExecutorService.

Learning about Threads

I have written a simple program, that is intended to start a few threads. The threads should then pick a integer n from an integer array, use it to wait n and return the time t the thread waited back into an array for the results.
If one thread finishes it's task, it should pick the next one, that has not yet being assigned to another thread.
Of course: The order in the arrays has to be maintained, so that integers and results match.
My code runs smoothly as far I see.
However I use one line of code block I find in particular unsatisfying and hope there is a good way to fix this without changing too much:
while(Thread.activeCount() != 1); // first evil line
I kinda abuse this line to make sure all my threads finish getting all the tasks done, before I access my array with the results. I want to do that to prevent ill values, like 0.0, Null Pointer Exception... etc. (in short anything that would make an application with an actual use crash)
Any sort of constructive help is appreciated. I am also not sure, if my code still runs smoothly for very very long arrays of tasks for the threads, for example the results no longer match the order of the integer.
Any constructive help is appreciated.
First class:
public class ThreadArrayWriterTest {
int[] repitions;
int len = 0;
double[] timeConsumed;
public boolean finished() {
synchronized (repitions) {
return len <= 0;
}
}
public ThreadArrayWriterTest(int[] repitions) {
this.repitions = repitions;
this.len = repitions.length;
timeConsumed = new double[this.len];
}
public double[] returnTimes(int[] repititions, int numOfThreads, TimeConsumer timeConsumer) {
for (int i = 0; i < numOfThreads; i++) {
new Thread() {
public void run() {
while (!finished()) {
len--;
timeConsumed[len] = timeConsumer.returnTimeConsumed(repititions[len]);
}
}
}.start();
}
while (Thread.activeCount() != 1) // first evil line
;
return timeConsumed;
}
public static void main(String[] args) {
long begin = System.currentTimeMillis();
int[] repitions = { 3, 1, 3, 1, 2, 1, 3, 3, 3 };
int numberOfThreads = 10;
ThreadArrayWriterTest t = new ThreadArrayWriterTest(repitions);
double[] times = t.returnTimes(repitions, numberOfThreads, new TimeConsumer());
for (double d : times) {
System.out.println(d);
}
long end = System.currentTimeMillis();
System.out.println("Total time of execution: " + (end - begin));
}
}
Second class:
public class TimeConsumer {
double returnTimeConsumed(int repitions) {
long before = System.currentTimeMillis();
for (int i = 0; i < repitions; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
long after = System.currentTimeMillis();
double ret = after - before;
System.out.println("It takes: " + ret + "ms" + " for " + repitions + " runs through the for-loop");
return ret;
}
}
The easiest way to wait for all threads to complete is to keep a Collection of them and then call Thread.join() on each one in turn.
In addition to .join() you can use ExecutorService to manage pools of threads,
An Executor that provides methods to manage termination and methods
that can produce a Future for tracking progress of one or more
asynchronous tasks.
An ExecutorService can be shut down, which will cause it to reject new
tasks. Two different methods are provided for shutting down an
ExecutorService. The shutdown() method will allow previously submitted
tasks to execute before terminating, while the shutdownNow() method
prevents waiting tasks from starting and attempts to stop currently
executing tasks. Upon termination, an executor has no tasks actively
executing, no tasks awaiting execution, and no new tasks can be
submitted. An unused ExecutorService should be shut down to allow
reclamation of its resources.
Method submit extends base method Executor.execute(Runnable) by
creating and returning a Future that can be used to cancel execution
and/or wait for completion. Methods invokeAny and invokeAll perform
the most commonly useful forms of bulk execution, executing a
collection of tasks and then waiting for at least one, or all, to
complete.
ExecutorService executorService = Executors.newFixedThreadPool(maximumNumberOfThreads);
CompletionService completionService = new ExecutorCompletionService(executorService);
for (int i = 0; i < numberOfTasks; ++i) {
completionService.take();
}
executorService.shutdown();
Plus take a look at ThreadPoolExecutor
Since java provides more advanced threading API with concurrent package, You should have look into ExecutorService, which simplifies thread management mechanism.
Simple to solution to your problem.
Use Executors API to create thread pool
static ExecutorService newFixedThreadPool(int nThreads)
Creates a thread pool that reuses a fixed number of threads operating off a shared unbounded queue.
Use invokeAll to wait for all tasks to complete.
Sample code:
ExecutorService service = Executors.newFixedThreadPool(10);
List<MyCallable> futureList = new ArrayList<MyCallable>();
for ( int i=0; i<12; i++){
MyCallable myCallable = new MyCallable((long)i);
futureList.add(myCallable);
}
System.out.println("Start");
try{
List<Future<Long>> futures = service.invokeAll(futureList);
for(Future<Long> future : futures){
try{
System.out.println("future.isDone = " + future.isDone());
System.out.println("future: call ="+future.get());
}
catch(Exception err1){
err1.printStackTrace();
}
}
}catch(Exception err){
err.printStackTrace();
}
service.shutdown();
Refer to this related SE question for more details on achieving the same:
wait until all threads finish their work in java

Java concurrency counter not properly clean up

This is a java concurrency question. 10 jobs need to be done, each of them will have 32 worker threads. Worker thread will increase a counter . Once the counter is 32, it means this job is done and then clean up counter map. From the console output, I expect that 10 "done" will be output, pool size is 0 and counterThread size is 0.
The issues are :
most of time, "pool size: 0 and countThreadMap size:3" will be
printed out. even those all threads are gone, but 3 jobs are not
finished yet.
some time, I can see nullpointerexception in line 27. I have used ConcurrentHashMap and AtomicLong, why still have concurrency
exception.
Thanks
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.atomic.AtomicLong;
public class Test {
final ConcurrentHashMap<Long, AtomicLong[]> countThreadMap = new ConcurrentHashMap<Long, AtomicLong[]>();
final ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
final ThreadPoolExecutor tPoolExecutor = ((ThreadPoolExecutor) cachedThreadPool);
public void doJob(final Long batchIterationTime) {
for (int i = 0; i < 32; i++) {
Thread workerThread = new Thread(new Runnable() {
#Override
public void run() {
if (countThreadMap.get(batchIterationTime) == null) {
AtomicLong[] atomicThreadCountArr = new AtomicLong[2];
atomicThreadCountArr[0] = new AtomicLong(1);
atomicThreadCountArr[1] = new AtomicLong(System.currentTimeMillis()); //start up time
countThreadMap.put(batchIterationTime, atomicThreadCountArr);
} else {
AtomicLong[] atomicThreadCountArr = countThreadMap.get(batchIterationTime);
atomicThreadCountArr[0].getAndAdd(1);
countThreadMap.put(batchIterationTime, atomicThreadCountArr);
}
if (countThreadMap.get(batchIterationTime)[0].get() == 32) {
System.out.println("done");
countThreadMap.remove(batchIterationTime);
}
}
});
tPoolExecutor.execute(workerThread);
}
}
public void report(){
while(tPoolExecutor.getActiveCount() != 0){
//
}
System.out.println("pool size: "+ tPoolExecutor.getActiveCount() + " and countThreadMap size:"+countThreadMap.size());
}
public static void main(String[] args) throws Exception {
Test test = new Test();
for (int i = 0; i < 10; i++) {
Long batchIterationTime = System.currentTimeMillis();
test.doJob(batchIterationTime);
}
test.report();
System.out.println("All Jobs are done");
}
}
Let’s dig through all the mistakes of thread related programming, one man can make:
Thread workerThread = new Thread(new Runnable() {
…
tPoolExecutor.execute(workerThread);
You create a Thread but don’t start it but submit it to an executor. It’s a historical mistake of the Java API to let Thread implement Runnable for no good reason. Now, every developer should be aware, that there is no reason to treat a Thread as a Runnable. If you don’t want to start a thread manually, don’t create a Thread. Just create the Runnable and pass it to execute or submit.
I want to emphasize the latter as it returns a Future which gives you for free what you are attempting to implement: the information when a task has been finished. It’s even easier when using invokeAll which will submit a bunch of Callables and return when all are done. Since you didn’t tell us anything about your actual task, it’s not clear whether you can let your tasks simply implement Callable (may return null) instead of Runnable.
If you can’t use Callables or don’t want to wait immediately on submission, you have to remember the returned Futures and query them at a later time:
static final ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
public static List<Future<?>> doJob(final Long batchIterationTime) {
final Random r=new Random();
List<Future<?>> list=new ArrayList<>(32);
for (int i = 0; i < 32; i++) {
Runnable job=new Runnable() {
public void run() {
// pretend to do something
LockSupport.parkNanos(TimeUnit.SECONDS.toNanos(r.nextInt(10)));
}
};
list.add(cachedThreadPool.submit(job));
}
return list;
}
public static void main(String[] args) throws Exception {
Test test = new Test();
Map<Long,List<Future<?>>> map=new HashMap<>();
for (int i = 0; i < 10; i++) {
Long batchIterationTime = System.currentTimeMillis();
while(map.containsKey(batchIterationTime))
batchIterationTime++;
map.put(batchIterationTime,doJob(batchIterationTime));
}
// print some statistics, if you really need
int overAllDone=0, overallPending=0;
for(Map.Entry<Long,List<Future<?>>> e: map.entrySet()) {
int done=0, pending=0;
for(Future<?> f: e.getValue()) {
if(f.isDone()) done++;
else pending++;
}
System.out.println(e.getKey()+"\t"+done+" done, "+pending+" pending");
overAllDone+=done;
overallPending+=pending;
}
System.out.println("Total\t"+overAllDone+" done, "+overallPending+" pending");
// wait for the completion of all jobs
for(List<Future<?>> l: map.values())
for(Future<?> f: l)
f.get();
System.out.println("All Jobs are done");
}
But note that if you don’t need the ExecutorService for subsequent tasks, it’s much easier to wait for all jobs to complete:
cachedThreadPool.shutdown();
cachedThreadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
System.out.println("All Jobs are done");
But regardless of how unnecessary the manual tracking of the job status is, let’s delve into your attempt, so you may avoid the mistakes in the future:
if (countThreadMap.get(batchIterationTime) == null) {
The ConcurrentMap is thread safe, but this does not turn your concurrent code into sequential one (that would render multi-threading useless). The above line might be processed by up to all 32 threads at the same time, all finding that the key does not exist yet so possibly more than one thread will then be going to put the initial value into the map.
AtomicLong[] atomicThreadCountArr = new AtomicLong[2];
atomicThreadCountArr[0] = new AtomicLong(1);
atomicThreadCountArr[1] = new AtomicLong(System.currentTimeMillis());
countThreadMap.put(batchIterationTime, atomicThreadCountArr);
That’s why this is called the “check-then-act” anti-pattern. If more than one thread is going to process that code, they all will put their new value, being confident that this was the right thing as they have checked the initial condition before acting but for all but one thread the condition has changed when acting and they are overwriting the value of a previous put operation.
} else {
AtomicLong[] atomicThreadCountArr = countThreadMap.get(batchIterationTime);
atomicThreadCountArr[0].getAndAdd(1);
countThreadMap.put(batchIterationTime, atomicThreadCountArr);
Since you are modifying the AtomicInteger which is already stored into the map, the put operation is useless, it will put the very array that it retrieved before. If there wasn’t the mistake that there can be multiple initial values as described above, the put operation had no effect.
}
if (countThreadMap.get(batchIterationTime)[0].get() == 32) {
Again, the use of a ConcurrentMap doesn’t turn the multi-threaded code into sequential code. While it is clear that the only last thread will update the atomic integer to 32 (when the initial race condition doesn’t materialize), it is not guaranteed that all other threads have already passed this if statement. Therefore more than one, up to all threads can still be at this point of execution and see the value of 32. Or…
System.out.println("done");
countThreadMap.remove(batchIterationTime);
One of the threads which have seen the 32 value might execute this remove operation. At this point, there might be still threads not having executed the above if statement, now not seeing the value 32 but producing a NullPointerException as the array supposed to contain the AtomicInteger is not in the map anymore. This is what happens, occasionally…
After creating your 10 jobs, your main thread is still running - it doesn't wait for your jobs to complete before it calls report on the test. You try to overcome this with the while loop, but tPoolExecutor.getActiveCount() is potentially coming out as 0 before the workerThread is executed, and then the countThreadMap.size() is happening after the threads were added to your HashMap.
There are a number of ways to fix this - but I will let another answer-er do that because I have to leave at the moment.

java multithreading - child thread does not start immediately

I am learning about MULTITHREADING in java and I want to know why in the following code, the child thread does not immediately run when the start method is executed to invoke the run method in the child thread?
Instead, after executing the start method, the main thread keeps executing its code and starts printing ".". Which it does three times and the control is taken over by the child thread. The child thread then executes its code one time and returns back to the main thread. Then main thread completes and then the child thread completes its execution as well.
I am unable to understand why this happens?
class MyThread implements Runnable {
String thrdName;
MyThread(String name) {
thrdName = name;
}
public void run() {
System.out.println(thrdName + " starting.");
for (int count = 0; count < 10; count++) {
System.out.println("In " + thrdName + ", count is " + count);
}
}
}
class UseThreads {
public static void main(String args[]) {
System.out.println("Main thread starting.");
MyThread mt = new MyThread("Child #1");
Thread newThrd = new Thread(mt);
newThrd.start();
for (int i = 0; i < 50; i++) {
System.out.print(".");
}
}
}
When you call start() on your thread, you get no guarantees on how fast it will start. This is up to the thread scheduler of your computer. If you run your code multiple times, you will likely get several different execution orders for your threads.
The call to begin a thread is asychronous. It does not wait until the thread has started running before returning; it returns essentially immediately.
You can implement that behaviour yourself, with a bit of locking, such that your main thread pauses until the thread you have begun issues a signal of some kind, to indicate it has begun execution.

Wait for one of several threads

I have a java application where the main-thread starts 2 other threads.
If one of these threads terminates, the main-thread may start another thread depending on the result of the terminated thread.
Example:
The main-thread creates 2 threads: A and B. Thread A will load a picture and thread B will load another picture. If A terminates and loaded the picture successfully a new Thread C will be created which does some other stuff and so on.
How can i do this? I do not want to use busy waiting in the main thread and check every 100ms if one of the two threads has finished.
I think i cannot use a thread pool because the number of active threads (in this case A and B) will vary extremely and it's the main-threads dicision to create a new thread or not.
This is rough sketch of the "busy waiting" solution:
public class TestThreads {
private class MyThread extends Thread {
volatile boolean done = false;
int steps;
#Override
public void run() {
for (int i=0; i<steps; i++) {
System.out.println(Thread.currentThread().getName() + ": " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException exc) { }
}
done = true;
synchronized (this) {
notify();
}
}
public void waitFor(long ms) {
synchronized (this) {
try {
wait(ms);
} catch (InterruptedException exc) { }
}
}
}
public void startTest() {
MyThread a = new MyThread();
a.steps = 6;
a.start();
MyThread b = new MyThread();
b.steps = 3;
b.start();
while (true) {
if (!a.done) {
a.waitFor(100);
if (a.done) {
System.out.println("C will be started, because A is done.");
}
}
if (!b.done) {
b.waitFor(100);
if (b.done) {
System.out.println("C will be started, because B is done.");
}
}
if (a.done && b.done) {
break;
}
}
}
public static void main(String[] args) {
TestThreads test = new TestThreads();
test.startTest();
}
}
This sounds like a classic case for using a ThreadPoolExecutor for performing the tasks concurrently, and wrapping it with an ExecutorCompletionService, for collecting the results as they arrive.
For example, assuming that tasks contains a set of tasks to execute in parallel, each returning a String value when it terminates, the code to process the results as they become available can be something like:
List<Callable<String>> tasks = ....;
Executor ex = Executors.newFixedThreadPool(10);
ExecutorCompletionService<String> ecs = new ExecutorCompletionService<String>(ex);
for (Callable<String> task : tasks)
ecs.submit(task);
for(int i = 0; i < tasks.size(); i++) {
String result = ecs.take().get();
//Do something with result
}
If you include the identity of the task as a part of the returned value, then you can make decisions depending on the completion order.
Check Semaphore
A counting semaphore. Conceptually, a semaphore maintains a set of permits. Each acquire() blocks if necessary until a permit is available, and then takes it
So, whenever you thread finishes, it frees one permit, which is then acquired by the main thread
You should use a thread pool. In a thread pool, you have a fixed number of threads and tasks are kept in a queue; whenever a thread is available, a task is taken off the queue and executed by that thread.
Here is a link to the Sun tutorial on thread pooling.
Edit: just noticed that you wrote in your answer that you think you cannot use thread pooling. I don't see why this is the case. You can set threads to be created on-demand rather than all at once if you are worried about creation overhead, and once created an idle thread is not really going to hurt anything.
You also say that it's the main thread's decision to create a new Thread or not, but does it really need to be? I think that may just overcomplicate things for you.
Is there a reason to control the thread execution directly instead of using something like
ExecutorService?
#danben got there first, but I fell into the same pooling trap.
A lot of the complexity in your code is that the main thread is trying to wait on two different objects. There's nothing which says you can't use wait and notify on another object, and if your tasks are ( A or B ) then C, the code below will work - wait on a reference which is set to indicate the first task to complete.
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.atomic.*;
public class BiggieThreads
{
private static class MyTask implements Runnable
{
final int steps;
final AtomicReference<MyTask> shared;
final String name;
MyTask ( int steps, AtomicReference<MyTask> shared, String name )
{
this.shared = shared;
this.steps = steps;
this.name = name;
}
#Override
public void run()
{
for ( int i = 1; i <= steps; i++ ) {
System.out.println ( "Running: " + this + " " + i + "/" + steps);
try {
Thread.sleep ( 100 );
} catch ( InterruptedException exc ) { }
}
// notify if this is the first to complete
if ( shared.compareAndSet ( null, this ) )
synchronized ( shared ) {
shared.notify();
}
System.out.println ( "Completed: " + this );
}
#Override
public String toString ()
{
return name;
}
}
public void startTest() throws InterruptedException
{
final ExecutorService pool = Executors.newFixedThreadPool ( 3 );
final AtomicReference<MyTask> shared = new AtomicReference<MyTask>();
Random random = new Random();
synchronized ( shared ) {
// tasks launched while lock on shared held to prevent
// them notifying before this thread waits
pool.execute ( new MyTask ( random.nextInt ( 5 ) + 3, shared, "a" ) );
pool.execute ( new MyTask ( random.nextInt ( 5 ) + 3, shared, "b" ) );
shared.wait();
}
System.out.println ( "Reported: " + shared.get() );
pool.shutdown();
}
public static void main ( String[] args ) throws InterruptedException
{
BiggieThreads test = new BiggieThreads ();
test.startTest();
}
}
I'd tend to use a semaphore for this job in production, as although the wait is quite simple, using in semaphore puts a name to the behaviour, so there's less to work out when you next read the code.

Categories

Resources