How to isolate variables between threads in Java? - java

I think I'm having race conditions when running my multithreaded Java program.
It's a permutation algorithm, which I want to speed up by running multiple instances with different values. So I start the threads in Main class with:
Runnable[] mcl = new MCL[n1];
for (int thread_id = 0; thread_id < n1; thread_id ++)
{
mcl[thread_id] = new MCL(thread_id);
new Thread(mcl[thread_id]).start();
Thread.sleep(100);
}
And it runs those MCL classes instances.
Again, I think threads are accessing the same memory space of the MCL class variables, am I right? If so, how can I solve this?
I'm trying to make all variables arrays, where one of the dimensions is related to an Id of the thread, so that each thread writes on a different index. Is this a good solution?:
int[] foo = new foo[thread_id];

You can't just bolt on thread safety as an afterthought, it needs to be an integral part of your data flow design.
To start, research and learn the following topics:
1) Synchronized blocks, mutexes, and final variables. A good place to start: Tutorial. I also love Josh Bloch's Effective Java, which although a few years old has golden nuggets for writing correct Java programs.
2) Oracle's Concurrency Tutorial
3) Learn about Executors. You shouldn't have to manage threads directly except in the most extreme cases. See this tutorial
If you pass non thread safe objects between threads you're going to see unpredictable results. Unpredictable means assignments may never show up between different threads, or objects may be left in invalid states (especially if you've got multiple member fields that have data dependent on each other).
Without seeing the MCL class we can't give you any specific details on what's dangerous, but given the code sample you've posted I think you should take a step back and do some research. In the long run it will save you time to learn it the right way rather than troubleshoot an incorrect concurrency scheme.

If you want to keep the thread data separate store it as instance variables in the Runnables (initializing each Runnable before starting its thread). Don't keep a reference to it in an array, that's just inviting trouble.
You can use a CompletionService to get a computed value back for each task wrapped in a Future, so you don't wait for it to be calculated until you actually need the value. The difference between a CompletionService and an Executor, which the commentors are recommending, is that the CompletionService uses an Executor for executing tasks, but it makes it easier to get your data back out, see this answer.
Here's an example of using a CompletionService. I'm using Callable instead of Runnable because I want to get a result back:
public class CompletionServiceExample {
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
ExecutorCompletionService<BigInteger> service =
new ExecutorCompletionService<BigInteger>(executorService);
MyCallable task1 = new MyCallable(new BigInteger("3"));
MyCallable task2 = new MyCallable(new BigInteger("5"));
Future<BigInteger> future1 = service.submit(task1);
Future<BigInteger> future2 = service.submit(task2);
System.out.println("submitted tasks");
System.out.println("result1=" + future1.get() );
System.out.println("result2=" + future2.get());
executorService.shutdown();
}
}
class MyCallable implements Callable<BigInteger> {
private BigInteger b;
public MyCallable(BigInteger b) {
this.b = b;
}
public BigInteger call() throws Exception {
// do some number-crunching thing
Thread.sleep(b.multiply(new BigInteger("100")).longValue());
return b;
}
}
Alternatively you can use the take method to retrieve results as they get completed:
public class TakeExample {
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newCachedThreadPool();
ExecutorCompletionService<BigInteger> service = new
ExecutorCompletionService<BigInteger>(executorService);
MyCallable task1 = new MyCallable(new BigInteger("10"));
MyCallable task2 = new MyCallable(new BigInteger("5"));
MyCallable task3 = new MyCallable(new BigInteger("8"));
service.submit(task1);
service.submit(task2);
service.submit(task3);
Future<BigInteger> futureFirst = service.take();
System.out.println(futureFirst.get());
Future<BigInteger> futureSecond = service.take();
System.out.println(futureSecond.get());
Future<BigInteger> futureThird = service.take();
System.out.println(futureThird.get());
executorService.shutdown();
}
}

Related

Finding the Names of active threads inside a threadpool : ExecutorService in java

So I am running an executor service and I would like to know the Names or the threadIDs of all the currently active/idle threads.
ExecutorService service = Executors.newCachedThreadPool(ThreadFactory threadFactory)
I do not need to know the count, but the actual names/IDs of all the active threads in my executor service. I need to identify the threads in any manner because I plan on implementing my own ThreadFactory with an appropriate naming convention.
For example, if my active threads are T0,T1,T3, my threadfactory would name the next thread as T2. But I can't find a way to get information about the active Threads.
How can I do that?
PS : Any other methods would also be appreciated. For example, lets say I am fine with having threads with names from T0 to T50. I just want my current threadfactory to assign any name from T0 to T50 such that a thread with the same name is not currently active or idle.
I was so free to create you a sample, of something I would've done. I couldn't really test it though:
public class CachingThreadFactory implements ThreadFactory{
// amount of active threads at max
private static final int THREAD_POOL_MAX_SIZE = 8;
// interval in milliseconds of the clean up task
private static final int CLEAN_UP_INTERVAL = 2000;
// the actual cache
private final Thread[] cachedThreads = new Thread[THREAD_POOL_MAX_SIZE];
// clean up task definition
{
new Timer().scheduleAtFixedRate(new CleanUpTask(), 0, CLEAN_UP_INTERVAL);
}
#Override
public synchronized Thread newThread(Runnable r){
for(int i = 0; i < cachedThreads.length; i++){
if(cachedThreads[i] == null){
return cachedThreads[i] = new Thread(r, "T" + i);
}
}
return null;
}
private final class CleanUpTask extends TimerTask{
#Override
public void run(){
synchronized(CachingThreadFactory.this){
for(int i = 0; i < cachedThreads.length; i++){
final Thread thread = cachedThreads[i];
if(thread != null && !thread.isAlive()){
cachedThreads[i] = null; // unset
}
}
}
}
}
}
This Factory caches every Thread it creates in an array. Then it runs a cleanUpTask asynchronly which checks if the threads in the array (if any) are still alive. If not they are removed.
The newThread method iterates through the cache, to find an index which is not yet taken, and then uses that index to create the name of that Thread. If no place is free it just returns null.
This class is probably thread safe. But I haven't really tested it. The synchronized-statements should prevent the interference between the cleanUp-Task and the newThread method. But any other action may disturb the whole thing.
call instead
Executors.newCachedThreadPool(ThreadFactory threadFactory)
and pass your implementation of ThreadFactory. There you can manage thread names at thread creation time.
Connect to your running program via jconsole or jvisual vm. It will give you all the running threads and their names.

Why is CompletableFuture.supplyAsync succeeding a random number of times?

I'm new to both lambdas and asynchronous code in Java 8. I keep getting some weird results...
I have the following code:
import java.util.concurrent.CompletableFuture;
public class Program {
public static void main(String[] args) {
for (int i = 0; i < 100; i++) {
String test = "Test_" + i;
final int a = i;
CompletableFuture<Boolean> cf = CompletableFuture.supplyAsync(() -> doPost(test));
cf.thenRun(() -> System.out.println(a)) ;
}
}
private static boolean doPost(String t) {
System.out.println(t);
return true;
}
}
The actual code is a lot longer, as the doPost method will post some data to a web service. However, I'm able to replicate my issue with this bare-bones code.
I want to have the doPost method execute 100 times, but asynchronously for performance reasons (in order to push data to the web service faster than doing 100 synchronous calls would be).
In the code above, the ´doPost´ method is run a random amount of times, but always no more than 20-25 times. There are no exceptions thrown. It seems that either some thread handling mechanism is silently refusing to create new threads and execute their code, or the threads are silently crashing without crashing the program.
I also have an issue where, if I add more functionality to the doPost method than shown above, it reaches a point where the method simply silently breaks. I've tried adding a System.out.println("test") right before the return statement in that case, but it is never called. The loop which loops 100 times does run 100 iterations though.
This behaviour is confusing, to say the least.
What am I missing? Why is the function supplied as an argument to supplyAsync run a seemingly random number of times?
EDIT: Just wanted to point out that the situation is not exactly the same as in the question this was marked as a possible duplicate of, as that question dealt with arbitrarily deeply nested futures, and this one deals with parallell ones. However, the reason why they are failing is virtually identical. The cases seem distinct enough to merit separate questions to me, but others might disagree...
By default CompletableFuture uses own ForkJoinPool.commonPool() (see CompletableFuture implementation). And this default pool creates only daemon threads, e.g. they won't block the main application from terminating if they still alive.
You have the following choices:
Collect all CompletionStage to some array and then make java.util.concurrent.CompletableFuture#allOf().toCompletableFuture().join() - this will guarantee all the stages are completed before going after join()
Use *Async operations with your own thread pool which contains only non-daemon threads, like in the following example:
public static void main(String[] args) throws InterruptedException {
ExecutorService pool = Executors.newFixedThreadPool(10, r -> {
Thread t = new Thread(r);
t.setDaemon(false); // must be not daemon
return t;
});
for (int i = 0; i < 100; i++) {
final int a = i;
// the operation must be Async with our thread pool
CompletableFuture<Boolean> cf = CompletableFuture.supplyAsync(() -> doPost(a), pool);
cf.thenRun(() -> System.out.printf("%s: Run_%s%n", Thread.currentThread().getName(), a));
}
pool.shutdown(); // without this the main application will be blocked forever
}
private static boolean doPost(int t) {
System.out.printf("%s: Post_%s%n", Thread.currentThread().getName(), t);
return true;
}

calling different methods of same class using multi threading in java

I have a class as below with three methods
public class MyRunnable implements Runnable {
#Override
public void run() {
// what code need to write here
//to call the specific methods based on request types
}
public int add(int a, int b){
return a+b;
}
public int multiply(int a , int b){
return a*b;
}
public int division(int a , int b){
return a/b;
}
}
and my main class as blow
here r.multiply(), add() and division() methods will be executed sequentially, but i want to execute them in multi-threaded way hence i can get the result faster. how to call a method of a class dynamically based on inputs. how to pass to thread and how to return result from thread to calling thread.
public class ThreadDemo {
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
// how to do below calculation using multihtreading
// how to call a method and how to get result of a thread of same class
int result = r.multiply(1, 2) + r.add(4, 5) + r.division(10, 5);
System.out.println(result);
int newResult = r.add(20, 50);
System.out.println(newResult);
}
}
Multi-threading would slow down this application (because the amount of processing per step is far to small to justify the overhead of distributing the work across threads), the application probably finishes well before you perceive it anyway.
Assuming it's a simplified example you can write
MyRunnable r = new MyRunnable();
Executor exec = Executors.newFixedThreadPool(3);
CompletableFuture<Integer> mult = CompletableFuture.runAsync(() -> r.multiply(1, 2),exec );
CompletableFuture<Integer> add = CompletableFuture.runAsync(() -> r.add(4, 5) ,exec);
CompletableFuture<Integer> div = CompletableFuture.runAsync(() -> r.division(10, 5),exec);
CompletableFuture<Integer> result = mult.thenCombine(add, (multRes,addRes) -> multRes+addRest)
.thenCombine(div, (total,divRes) -> total+divRes);
int answer = result.join();
UPDATE Why use an explicitly defined Executor?
It shows readers how to explicitly define an executor (the alternative is straightforward)
By defining the Executor as a variable, you can switch between the Common ForkJoinPool (or any other executor type) by changing just that variable assignment (you don't have to refactor all of the methods). E.g.
//ForkJoinPool common
Executor exec = ForkJoinPool.commonPool();
//Expanding thread pool
Executor exec = Executors.newCachedThreadPool();
//Just execute on the current thread
Executor exec = (Runnable r) -> r.run();
By default CompletableFuture.*Async methods share the Common ForkJoinPool and so do Parallel Streams, along with ForkJoinTasks without a specific executor. Unless all members of the team think carefully about when to / not to use the Common ForkJoinPool you could end up mixing async I/O operations with CPU bound processing in the same pool accidentally.
Also by default, the parallelism is set to Runtime.getRuntime().availableProcessors() - 1. Which again, may or may not suit the use case at hand (for some users it might mean this example was single threaded). It is configurable via the System Property "java.util.concurrent.ForkJoinPool.common.parallelism", if you need to change the defaults.

Differeance in creating threads from same class or different classes implemeting runnable [duplicate]

Is it bad programming to initialize two threads with the same instance of a runnable? What difference would it make to initialize with separate instances of a runnable, and does sharing memory locations at all for the same instance of a runnable have anything to do with performance?
public static void main(String[] args)throws Exception {
H h = new H();
H h2 = new H();
Thread j = new Thread(h);
j.setName("11");
Thread jj = new Thread(h);//instead of new H()
jj.setName("22");
j.start();
jj.start();
}
class H implements Runnable {
public void run() {
while(true) {
System.out.println(Thread.currentThread().getName());
}
}
}
It's absolutely fine to do it so long as the code you're running is designed to support that. Not only will it save some memory by having a single instance instead of multiple instances, but if those threads are trying to communicate via shared data, then it may be absolutely required!
Admittedly communicating via shared state is where threading often gets tricky, so this needs to be done carefully, but from the point of view of the threading system itself, there's absolutely no problem in having two threads call the run method of a single Runnable instance.
Since H doesn't have any instance state, using multiple instances won't matter. You need to take care when the Runnable instances start storing state.
public class Main implements Runnable {
volatile int i;
public void run() {
for (i = 0; i < 100; i++) {
System.out.println(i);
}
}
public static void main(String[] args) {
Main a = new Main();
Thread t1 = new Thread(a);
Thread t2 = new Thread(a);
t1.start();
t2.start();
}
}
What gets printed? When you do need to share state between threads, it's a good idea to use the classes in java.util.concurrent. They were written primarily by an expert in multithreading (Doug Lea, author of Concurrent Programming in Java) and tested by many people. Save yourself some heartache. :)
Is it bad programming to initialize two threads with the same instance of a runnable?
Not specifically. However, if the Runnable instance has instance fields, then you'll need to make sure that all access to the fields by the thread is properly synchronized, and this will make the code more complicated.
What difference would it make to initialize with separate instances of a runnable, and does sharing memory locations at all for the same instance of a runnable have anything to do with performance?
The memory saved by sharing a Runnable instance between multiple threads is insignificant ... unless the Runnable holds a significant amount of instance data. (And if it does, the chances are that this will make the instance non-shareable.)
Your H class is an example where sharing instances is safe, but pointless since the memory saving is insignificant. (A Runnable object with no instance fields occupies roughly 8 to 16 bytes, depending on the platform.)
To make understand easily(based on the comment of Stephen), added the below program block about the impact of accessing the instance variable from a non-synchronized block with the same instance of Runnable displays the unexpected results.
public class SynchronizedInstanceMethod implements Runnable{
private int counter;
public SynchronizedInstanceMethod(int counterValue){
this.counter = counterValue;
}
private synchronized void displayMessage(){
System.out.println(" Display Message ");
}
private void modifyCounter(){
this.counter++;
System.out.println("Value -- "+ this.counter);
}
#Override
public void run() {
this.displayMessage();
this.modifyCounter();
}
public static void main(String[] args) {
SynchronizedInstanceMethod instance = new SynchronizedInstanceMethod(5);
new Thread(instance).start();
new Thread(instance).start();
}
}

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.

Categories

Resources