public class ConTest {
#Test
void name2() {
final MyCounter myCounter = new MyCounter();
final Thread t1 = new Thread(() ->
myCounter.increment()
);
final Thread t2 = new Thread(() ->
myCounter.increment()
);
t1.start();
t2.start();
System.out.println(myCounter.count);
}
#Test
void name3() {
final MyCounter myCounter = new MyCounter();
final ExecutorService service = Executors.newFixedThreadPool(2);
for (int i = 0; i < 2; i++) {
service.execute(() -> {
myCounter.increment();
});
}
System.out.println(myCounter.count);
}
static class MyCounter {
private AtomicLong count = new AtomicLong();
public void increment() {
count.incrementAndGet();
}
}
}
AtomicLong is safe when multi thread.
That is, in the example above, it was executed with 2 threads, so the result should be 2 no matter how many times it is executed.
However, after trying both tests several times, the result is sometimes 1. Why is this happening?
You aren't waiting for any of the background threads or tasks to end before you print the value of the counter. To wait on the tasks to exit, you'll need to add this for threads:
t1.join();
t2.join();
Add this for the service, which prevents new tasks being added and waits a sensible period for them to end:
service.shutdown();
boolean done = awaitTermination(pickSuitablyLongPeriod, TimeUnit.MILLISECONDS);
Once you have ensured the background tasks are completed, the correct result should be printed when you run:
System.out.println(myCounter.count);
This is because the threads are still processing when you call the System.out.println. In this case you would need to block the main thread before you print out the counter.
in the example of the Executor you can just await the termination:
final ExecutorService service = Executors.newFixedThreadPool(2);
final MyCounter myCounter = new MyCounter();
for (int i = 0; i < 100; i++) {
service.submit(myCounter::increment);
}
service.shutdown();
while (!service.awaitTermination(100, TimeUnit.MILLISECONDS)) {
System.out.println("waiting");
}
System.out.println(myCounter.count);
you should avoid to block in productive code, have a look at the Publish/Subscribe design pattern
dont forget to use shutdown() with Executors
see the comments here :
// Here you start the 2 threads
for (int i = 0; i < 2; i++) {
service.execute(() -> {
myCounter.increment();
});
}
// we are not sure here that your 2 threads terminate their tasks or not !!
// the print will be executed by the Main Thread and maybe before the 2 threads terminate their
// job ,
// maybe just one terminate , maybe no one from your 2 threads increment the count .
System.out.println(myCounter.count);
You can use Future class , instead of execute you can use submit() , the retrun type will be of Type Futre<?> (accept void ) , after that with the Future object returned the method get() will block the execution until the result returned from the service :
Example method name3() : will return always 2
void name3() {
final MyCounter myCounter = new MyCounter();
final ExecutorService service = Executors.newFixedThreadPool(2);
Future<?> f = null;
for (int i = 0; i < 2; i++) {
f =service.submit(() -> {
myCounter.increment();
});
try {
f.get();
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(myCounter.count);
service.shutdown();
}
In addition to the above answers, you could add some prints to better understand what is happening.
In summary. You need to wait for the threads to finish executing before expecting the results, so it is not an issue of AtomicLong.
I modified the code, added some prints, and here are results from an execution.
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicLong;
import org.junit.jupiter.api.Test;
public class ConTest {
#Test
void name2() {
final MyCounter myCounter = new MyCounter();
final Thread t1 = new Thread(() -> {
myCounter.increment();
System.out.println("Counter increment t1 completed and the value is " + myCounter.getCount());
});
final Thread t2 = new Thread(() -> {
myCounter.increment();
System.out.println("Counter increment t2 completed and the value is " + myCounter.getCount());
});
t1.start();
t2.start();
System.out.println(myCounter.count.get());
}
#Test
void name3() {
final MyCounter myCounter = new MyCounter();
final ExecutorService service = Executors.newFixedThreadPool(2);
for (int i = 0; i < 2; i++) {
service.execute(() -> {
myCounter.increment();
System.out.println("incrementing for count and the value is " + myCounter.getCount());
});
}
System.out.println(myCounter.count.get());
}
class MyCounter {
private AtomicLong count = new AtomicLong();
public void increment() {
count.incrementAndGet();
}
public long getCount(){
return count.get();
}
}
}
Results (name2)
1
Counter increment t1 completed and the value is 1
Counter increment t2 completed and the value is 2
Results (name3)
incrementing for count and the value is 1
1
incrementing for count and the value is 2
You could also use a debugger to have a better understanding.
Related
While testing concurrency, I found something unexpected.
Concurrency was controlled using concurrentHashMap and AtomicLong.
public class HumanRepository {
private final static Map<Long, Human> STORE = new ConcurrentHashMap<>();
private AtomicLong sequence = new AtomicLong();
public void save(Human human) {
STORE.put(sequence.incrementAndGet(), human);
}
public int size() {
return STORE.size();
}
public Long getSeq() {
return sequence.get();
}
}
I tested saving in multiple threads.
#Test
void name() throws NoSuchMethodException, InterruptedException {
final int threads = 3_500;
final ExecutorService es = Executors.newFixedThreadPool(threads);
final CountDownLatch count = new CountDownLatch(threads);
final HumanRepository repository = new HumanRepository();
for (int i = 0; i < threads; i++) {
try {
es.execute(() -> repository.save(new Human("aa")));
} finally {
count.countDown();
}
}
count.await();
System.out.println("seq = " + repository.getSeq());
System.out.println("size = " + repository.size());
}
I tested it with 3500 threads simultaneously. The result I expected is 3500 for both seq and size.
But sometimes I get seq=3499, size=3500.
That's weird. It is strange that seq does not come out as 3500, and even though the size is 3500, it does not make sense that seq is 3499.
I don't know why the data number and seq in the map are not the same and 3500 is not coming out.
** If you do Thread.sleep(400L); after count.await();, surprisingly, the value of seq is 3500
You are not actually waiting for all tasks to complete. Which means that if you get the 3500/3500 output, it's by chance.
Specifically, you decrease the countdown latch on the main thread after scheduling the job, instead of inside of the job, once it's done. That means your countdownlatch is basically just another glorified loop variable that doesn't do any inter-thread communication. Try something like this instead:
for (int i = 0; i < threads; i++) {
es.execute(() -> {
repository.save(new Human("aa"));
count.countDown();
});
}
You are calling count.countDown() outside the thread executing the HumanRepository.save(). So its possible that the main thread is not synchronized for the completion of the threads.
So you may see the results of repository.getSeq() while one thread is running. Can you try with the following code?
final int threads = 3_500;
final ExecutorService es = Executors.newFixedThreadPool(threads);
final CountDownLatch count = new CountDownLatch(threads);
final HumanRepository repository = new HumanRepository();
for (int i = 0; i < threads; i++) {
try {
es.execute(() -> {
repository.save(new Human("aa"));
count.countDown();
});
} finally {
}
}
count.await();
System.out.println("seq = " + repository.getSeq());
System.out.println("size = " + repository.size());
I'd like to keep a counter of executed threads, to use in the same threads that I am executing.
The problem here is that although the counter increases, it increases unevenly and from the console output I got this (I have a for loop that executes 5 threads with ExecutorService):
This is a test. N:3
This is a test. N:4
This is a test. N:4
This is a test. N:4
This is a test. N:4
As you can see instead of getting 1,2,3,4,5 I got 3,4,4,4,4.
I assume this is because the for loop is running fast enough to execute the threads, and the threads are fast enough to execute the code requesting for the counter faster than the counter can update itself (does that even make sense?).
Here is the code (it is smaller and there is no meaningful use for the counter):
for (int i = 0; i < 5; i++)
{
Thread thread;
thread = new Thread()
{
public void run()
{
System.out.println("This is test. N: "+aldo );
//In here there is much more stuff, saying it because it might slow down the execution (if that is the culprit?)
return;
}
};
threadList.add(thread);
}
//later
for (int i = 0; i < threadList.size(); i++)
{
executor.execute(threadList.get(i));
aldo = aldo + 1;
}
executor.shutdown();
try
{
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
}
catch (InterruptedException e)
{
}
Yes, aldo the counter ( with a few other lists, I think) are missing from the code (they are very simple).
The best way I know of doing this is by creating a custom thread class with a constructor that passes in a number. The variable holding the number can then be used later for any needed logging. Here is the code I came up with.
public static void main(String[] args) {
class NumberedThread implements Runnable {
private final int number;
public NumberedThread(int number) {
this.number = number;
}
#Override
public void run() {
System.out.println("This is test. N: " + number);
}
}
List<Thread> threadList = new ArrayList<>();
for (int i = 1; i < 6; i++) threadList.add(new Thread(new NumberedThread(i)));
ExecutorService executor = Executors.newFixedThreadPool(10);;
for (Thread thread : threadList) executor.execute(thread);
executor.shutdown();
try {
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
}
catch (InterruptedException ignored) { }
}
You could also use a string object instead if you wanted to name the threads.
aldo is not modified by the tasks in the thread, but instead is modified in the main thread, here:
for (int i = 0; i < threadList.size(); i++) {
executor.execute(threadList.get(i));
//here...
aldo = aldo + 1;
}
Also, since you want a counter that can increase its value in several threads, then you may use an AtomicInteger rather than int.
Your code should look like this:
AtomicInteger aldo = new AtomicInteger(1);
for (int i = 0; i < 5; i++) {
executor.execute( () -> {
System.out.println("This is test. N: " + aldo.getAndIncrement());
});
}
Lets say I have n threads concurrently taking values from a shared queue:
public class WorkerThread implements Runnable{
private BlockingQueue queue;
private ArrayList<Integer> counts = new ArrayList<>();
private int count=0;
public void run(){
while(true) {
queue.pop();
count++;
}
}
}
Then for each thread, I want to count every 5 seconds how many items it has dequeued, and then store it in its own list (counts)
I've seen here Print "hello world" every X seconds how you can run some code every x seconds:
Timer t = new Timer();
t.scheduleAtFixedRate(new TimerTask(){
#Override
public void run(){
counts.add(count);
count = 0
}
}, 0, 5000);
The problem with this is that I can't access count variable and the list of counts unless they are static. But I don't want them to be static because I don't want the different threads to share those variables.
Any ideas of how to handle this?
I don't think it's possible to use scheduled execution for you case(neither Timer nor ScheduledExecutorService), because each new scheduled invocation will create a new tasks with while loop. So number of tasks will increase constantly.
If you don't need to access this list of counts in runtime i would suggest something like this one:
static class Task implements Runnable {
private final ThreadLocal<List<Integer>> counts = ThreadLocal.withInitial(ArrayList::new);
private volatile List<Integer> result = new ArrayList<>();
private BlockingQueue<Object> queue;
public Task(BlockingQueue<Object> queue) {
this.queue = queue;
}
#Override
public void run() {
int count = 0;
long start = System.nanoTime();
try {
while (!Thread.currentThread().isInterrupted()) {
queue.take();
count++;
long end = System.nanoTime();
if ((end - start) >= TimeUnit.SECONDS.toNanos(1)) {
counts.get().add(count);
count = 0;
start = end;
}
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
// the last value
counts.get().add(count);
// copy the result cause it's not possible
// to access thread local variable outside of this thread
result = counts.get();
}
public List<Integer> getCounts() {
return result;
}
}
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(3);
BlockingQueue<Object> blockingQueue = new LinkedBlockingQueue<>();
Task t1 = new Task(blockingQueue);
Task t2 = new Task(blockingQueue);
Task t3 = new Task(blockingQueue);
executorService.submit(t1);
executorService.submit(t2);
executorService.submit(t3);
for (int i = 0; i < 50; i++) {
blockingQueue.add(new Object());
Thread.sleep(100);
}
// unlike shutdown() interrupts running threads
executorService.shutdownNow();
executorService.awaitTermination(1, TimeUnit.SECONDS);
System.out.println("t1 " + t1.getCounts());
System.out.println("t2 " + t2.getCounts());
System.out.println("t3 " + t3.getCounts());
int total = Stream.concat(Stream.concat(t1.getCounts().stream(), t2.getCounts().stream()), t3.getCounts().stream())
.reduce(0, (a, b) -> a + b);
// 50 as expected
System.out.println(total);
}
Why not a static AtomicLong?
Or the WorkerThread(s) can publish that they poped to the TimerTask or somewhere else? And the TimerTask reads that info?
Am new to java programming and first time using countDown in java,
My code snippet is,
CountDownLatch latch=new CountDownLatch(rows*columns); //rows -2 , columns -3
for (int i = 0; i < rows; i++) {
for (int j = 0; j < columns; j++) {
GUIView view = getView(1, 1);
if(view == null) {
if(ViewColumn(j +1) != null){
latch.countDown(); //EDT
continue;
}
latch.countDown(); //EDT
break;
}
new Thread(new countDownThread(view,latch)).start(); //Where i do some other processing and do countDown
}
}
try {
logger.log("Before countdown await");
latch.await();
logger.log("After countdown await");
}
.........
........
As i read from another post,
One of the disadvantages/advantages of CountDownLatch is that its not
reusable once count reaches to zero you can not use CountDownLatch any
more.
My doubt here is am using the same instance latch , inside the for loop. if CountDownLatch is not reusable what will happen if the first iteration latch.countDown() starts and it became zero by third iteration(The latch.countDown() at third iteration is not valid??).
The problem is :
When i debug the for loop(using eclipse), and when control reaches latch.await(); it just hangs. However, if i just run the application no hang happens.
I don't quite understand usage of countDown latch. Please explain me on the same.
Seems here you don't use multithreading, and all work done in one thread, because of you needn't to use CountDownLatch.
Also latch.await(); hang because it waiting for all count of tasks will be done(seems here it //rows -2 , columns -3 = 6) and call latch.countDown();. Read more about in docs.
Here is simple example of use, where t2 wait for t1:
import java.util.concurrent.CountDownLatch;
public class Test {
public static void main(String... s){
final CountDownLatch cdl = new CountDownLatch(1);
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
int i = 5;
while(i-- > 0)
System.out.println("t2 wait me");
cdl.countDown();
}
});
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
try {
cdl.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("done");
}
});
t2.start();
t1.start();
}
}
When you initialize CountDownLatch with some value for example:
CountDownLatch latch = new CountDownLatch(3);
It basically means that when method:
latch.countDown();
will be fired three times, the class which will use latch will be released from the await method call.
Of course you must ensure that the same instance of latch is used.
For more information go to nice tutorial: http://tutorials.jenkov.com/java-util-concurrent/countdownlatch.html
I have a requirement in which 28 threads have to complete some functionality. I have created these threads as in anonymous inner classes like :
Thread t=new Thread(new Runnable(){public void run()
{//code
}}
);
t.start();
Now I want that the further execution should start after all these threads have finished there work.
Note : I am confused about join() method as it makes my threads run sequentially.
So can anyone suggest me how can I make main thread run once these threads are done with work.
Note : I am confused about join() method as it makes my threads run sequentially.
It will do that if you have code like this:
for (Runnable runnable : runnables) {
Thread t = new Thread(runnable);
t.start();
t.join();
}
However, you can start all the threads you want to run in parallel, then call join on them all. For example:
List<Thread> threads = new ArrayList<>();
for (Runnable runnable : runnables) {
Thread t = new Thread(runnable);
t.start();
threads.add(t);
}
// Now everything's running - join all the threads
for (Thread thread : threads) {
thread.join();
}
// Now you can do whatever you need to after all the
// threads have finished.
There are many other approaches, of course - starting threads directly may well not be as suitable in your code as using a higher level abstraction; it depends on what you're trying to achieve. The above should work fine though - assuming all the Runnables are able to run in parallel without blocking each other through synchronization.
Make use of CountDownLatch.
public static void main(String... args) {
final CountDownLatch latch = new CountDownLatch(28);
for(int i=0;i<28;i++) {
Thread t=new Thread(new Runnable(){
public void run()
{
try {
//code
} finally {
latch.countDown();
}
}
});
t.start();
}
latch.await();
// Continue Code
}
Use a CountDownLatch and wait for all your threads to complete. :) .
PS : I gotto agree, using join() is also correct and more efficient.
example code :
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("t1 : " + i);
}
}
});
t1.start();
Thread t2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println("t2 : " + i);
}
}
});
t2.start();
t1.join();
t2.join();
System.out.println("main");
}
O/P :
t1 : 0
t1 : 1
t2 : 0
t1 : 2
t1 : 3
t2 : 1
t1 : 4
t1 : 5
t2 : 2
t1 : 6
t1 : 7
t2 : 3
t1 : 8
t1 : 9
t2 : 4
t2 : 5
t2 : 6
t2 : 7
t2 : 8
t2 : 9
main
According to the behaviour you're giving for join, I'm guessing you're starting and joining the threads within a single loop.
If you check the javadoc on this page, you'll note that a call to join will halt the execution of the calling thread until the other thread has finished executing.
You might want to keep an array or a list of threads when creating them, and starting them all in one loop, and only then joining them all.
Thread[] workers = new Thread[28];
for (int i = 0; i < workers.length; i++) {
workers[i] = new Thread { ... };
}
// Start running all threads
for (Thread worker: workers) {
worker.start();
}
// Make sure all threads are completed
for (Thread worker: workers) {
worker.join(); // if the worker already stopped, it'll return immediately.
}
// Now all threads have finished running and you can start post-processing
It's not the most elegant solution, but it'll do the trick.
As mentioned by others, you should probably use a CountDownLatch (haven't used one yet, so I can't provide feedback)
Edit: I've been beaten to it by Jon Skeet, sorry for the redundant answer...
CountDownLatch is better option.
I have created dummy program.
In this program I am sum 1000 number. I created 10 thread. In main thread I am doing dome of all child thread sum. you will get understand to simply viewing the code.
package Test1;
import java.util.concurrent.CountDownLatch;
class Sum extends Thread {
private int from;
private int to;
private int sum = 0;
CountDownLatch latch;
public int getSum() {
return sum;
}
public Sum(int from, int to, CountDownLatch latch) {
this.from = from;
this.to = to;
this.latch = latch;
}
public void run() {
for (int i = from; i < to; i++) {
sum += i;
}
latch.countDown();
}
}
public class Test5 {
public static void main(String[] args) throws InterruptedException {
int n = 1000;
int tn = 10;
int from = 1;
int to;
int sum = 0;
Sum[] sumArray = new Sum[tn];
final CountDownLatch latch = new CountDownLatch(tn);
for (int i = 0; i < tn; i++) {
to = from + n / tn;
Sum s = new Sum(from, to, latch);
sumArray[i] = s;
s.start();
from = to;
}
// Thread.sleep(1000);
latch.await();
for (int i = 0; i < tn; i++) {
sum += sumArray[i].getSum();
}
System.out.println(sum);
}
}