Java - BlockingQueue freezes multithread application - java

I'm making an application that contains of two threads: one of them writes a value to LinkedBlockingQueue, another is reading. I'm using ScheduledExecutorService for running this operations in some period in seconds.
The problem is that my application is freezing on the method take of BlockingQueue and i cant understand why.
This is a common resourse:
class Res{
AtomicInteger atomicInteger = new AtomicInteger(0);
BlockingQueue<String> q = new LinkedBlockingQueue<>();
}
This is reader
Semaphore semaphore = new Semaphore(1); /this is for reader does not take two places in thread pool
Runnable reader = ()->{
try {
semaphore.acquire();
System.out.println(res.q.take()+" "+res.atomicInteger.incrementAndGet());
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Writer:
Runnable writer = ()->{
res.q.add("hi");
};
Full code:
class Res{
AtomicInteger atomicInteger = new AtomicInteger(0);
BlockingQueue<String> q = new LinkedBlockingQueue<>();
}
public class Main {
public static void main(String[] args) throws InterruptedException {
ScheduledExecutorService executorService = Executors.newScheduledThreadPool(2);
Res res = new Res();
Semaphore semaphore = new Semaphore(1); //this is for reader does not take two places in thread pool
Runnable reader = ()->{
try {
semaphore.acquire();
System.out.println(res.q.take()+" "+res.atomicInteger.incrementAndGet());
semaphore.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Runnable writer = ()->{
res.q.add("hi");
};
Random rnd = new Random();
for (int i = 0; i < 20; i++) {
int time = rnd.nextInt(5)+ 2;
executorService.schedule(writer,time, TimeUnit.SECONDS);
}
for (int i = 0; i < 20; i++) {
int time = rnd.nextInt(5)+ 2;
executorService.schedule(reader,time, TimeUnit.SECONDS);
}
executorService.shutdown();
}
It should print twenty lines "hi [number]", but freezes on some line.
For example, my current print:
hi 1
hi 2
hi 3
hi 4
hi 5
I found out If i increase count of threads newScheduledThreadPool(20) it starts work, but how can I make it with two threads? Thanks!

It's a bit hard to follow your code, though it is obvious at the same time what is going on. You can run two threads at a time, at most, because of Executors.newScheduledThreadPool(2);. Both of these threads are reader threads.
So Thread-1 entered the try block and acquired the semaphore permit via semaphore.acquire();, but the queue was empty - as such it blocks on res.q.take(). The next thread - Thread-2 is a reader thread too, but it can not acquire a permit, since it is already taken by Thread-1 and is blocked on semaphore.acquire();. Since you have no room for other Threads (you pool is blocked working with these two Threads), there are no writers that would put something in your queue and as such unblock Thread-1 (so that res.q.take() would work).
Adding more worker Threads just delays the problem - you could end up in the same position as you were before.

Related

How to run a task once every Threads finished running in Java?

I have a loop which create a new Thread on each iteration, like so:
for(int i = 0; i < REPEAT; i++) {
new Thread(new MyTask(i)).start();
Thread.sleep(1);
}
private void finalTask() {
//Some code to be executed once every threads stopped running
}
Where MyTask is a class implementing Runnable. My goal is: I would like to run finalTask once every threads stopped. To achieve this, I have tried incrementing a variable by 1 each time a thread finished running, and once this variable was equal to REPEAT, the final task would run. But this didn't work. I've searched on Google and StackOverlow for answers to my problem, but there are very little informations on this and none of them worked as well. There would always be a thread that was running after the final task. How can I do this then?
You can use a CountDownLatch for this. A CountDownLatch is
A synchronization aid that allows one or more threads to wait until a set of operations being performed in other threads completes.
CountDownLatch countDownLatch = new CountDownLatch(REPEAT);
for (int i = 0; i < REPEAT; i++) {
new Thread(new MyTask(i, countDownLatch)).start();
Thread.sleep(1);
}
finalTask(countDownLatch);
I create a CountDownLatch whose count is initialized to the value of REPEAT. I pass this to each of the threads and to the finalTask method.
Each thread after doing its work should call the countDown method of the countDownLatch.
private static class MyTask implements Runnable {
private int i;
private CountDownLatch countDownLatch;
private MyTask(int i, CountDownLatch countDownLatch) {
this.i = i;
this.countDownLatch = countDownLatch;
}
#Override
public void run() {
//Perform some task
System.out.println("Running " + i);
countDownLatch.countDown();
}
}
The first line of the finalTask method should call the await method of the CountDownLatch. This will cause the thread running the finalTask wait till the count of the CountDownLatch reaches 0 i.e., until all threads (REPEAT number of them) has completed and invoked the countDown of the CountDownLatch.
private static void finalTask(CountDownLatch countDownLatch) {
try {
countDownLatch.await(); //this will wait until the count becomes 0.
} catch (InterruptedException e) {
e.printStackTrace(); //handle it appropriately
}
//Some code to be executed once all threads stopped running
System.out.println("All done");
}
Another simple way is to just join() on all the threads and then call finalTask():
Thread tasks[] = new Thread[REPEAT];
for(int i = 0; i < REPEAT; i++) {
tasks[i] = new Thread(new MyTask(i));
tasks[i].start();
}
for (Thread task : tasks) {
for (;;) {
try {
task.join();
break;
}
catch ( InterruptedException e ) {
// catch code here
}
}
}
finalTask();
Note there's almost more code used to handle the possible InterruptedException from the join() method call than used to implement the rest of the processing.
You can put them into CompletableFutures and then use whenComplete() .
CompletableFuture[] all =
IntStream.range(0, REPEAT+1).
.mapToObj(i -> CompletableFuture.supplyAsync(new MyTask(i)))
.toArray(CompletableFuture[]::new) ;
CompletableFuture.allOf(all).whenComplete((r, t) -> {
// your code here
}) ;

How to pass an integer/other variables between threads in java?

I have four threads running and I want to throw a flag when they're all done. What I want to do is have an int set to 0. When a thread finishes it'll add 1 to that int. I'll have an if statement at the end that'll have the condition that the int has to equal 4. When that happens a message will show up indicating that all the threads are done. However, when I try to do this it says ints have to be final or effectively final. How do I get around this?
The easiest way is just to use Thread.join():
Thread[] ts = new Thread[4];
for (int i = 0; i < 4; ++i) {
ts[i] = new Thread(...);
ts[i].start();
}
for (int i = 0; i < ts.length; ++i) {
ts[i].join(); // Wait for the i-th thread to die.
}
Amongst other alternatives, you can use a CountdownLatch, which gives you a little bit more flexibility as to when the thread is considered "finished":
Thread[] ts = new Thread[4];
final CountdownLatch latch = new CountdownLatch(ts.length);
for (int i = 0; i < 4; ++i) {
ts[i] = new Thread(new Runnable() {
#Override public void run() {
// ...
latch.countDown();
}
});
ts[i].start();
}
latch.await(); // Blocks until all threads have called `countDown()`.
There are many ways you can do that. If you want your main thread to be blocked while your other 4 threads are running, you can do
t1.join();
t2.join();
t3.join();
t4.join();
And this way your main thread will wait for the execution of all the other threads. If you want each thread to increment your flag, you can pass it in their constructors, but you should make the flag AtomicInteger
Another way to solve this is to use ThreadPool. You can make a ThreadPool of four threads and assign four Runnable tasks to them. Then you can invoke the .submit(Runnable) method to the threads. This way the 4 threds would execute the four tasks.
The .submit() method of the ExecutorService (which is the object that operates with the 4 threads) returns a so-called Future object. When invoking future.get() you will know that the thread has finished its task:
ExecutorService executor = Executors.newFixedThreadPool(4);
ArrayList<Runnable> tasks = new ArrayList<>();
tasks.add(new MyThread());
tasks.add(new MyThread());
tasks.add(new MyThread());
tasks.add(new MyThread());
ArrayList<Future> results = new ArrayList<>();
for(Runnable t : tasks){
results.add(executor.submit(t));
}
int myIntFlag = 0;
for(Future f : results){
f.get();
myIntFlag++;
System.out.println("Part" + myIntFlag + " of the job is ready")
}
System.out.println("Whole Job ready")
There are multiple ways you can achieve the same. Use any of them:
(a) Use Atomic Integer as flag and increase the flag count
(b) use CountdownLatch
(c) you can also tune cyclicbarrier for that (barrier at the end of each thread).
(d) use Thead.join()
~ Java Guru:
Blogger at Java Interview Questions and Answers
If you really want an int counter variable, you could either mark it as volatile or use an AtomicInteger.
volatile int counter = 0;
or
final AtomicInteger counter = new AtomicInteger();
Keep in mind that you'll have to loop polling this variable in your main thread until it is 4. If for some reason one of the threads don't get to increment it, your main thread will hang forever.

Semaphores used for signaling in threads not working(concurrency issue)

in this project I am trying to do some concurrency among threads using semaphores as signaling, however the concurrency is not working at all. I can only use acquire and release and no synchronized keyword methods allowed. I read countless webpages and it says that
// do something
acquire()
release()
//do something
Which I understand but in this program I am trying to test signals with a semaphore between threads, for example user requests deposit and teller should say deposit completed.However my signals(semaphores) are not working as I want to print in order for example
I need to deposit
Deposit is complete
instead I get this
Customer0created
I need to deposit
I have withdrawn <---
Customer0joined from main
Teller0created
You wanna withdrawal? <---- (out of order)
Deposit is complete
Regardless how i reorder them or how much i read the semaphore signaling to comm threads is not working.
[code]import java.util.concurrent.Semaphore;
public class Threads {
private static Semaphore depositTransaction = new Semaphore (1, true);
private static Semaphore withdrawal = new Semaphore (1, true);
public static void main(String[] args)
{
final int customerThreads = 1;
final int tellerThreads = 1;
final int loanThreads = 1;
Customer thr[] = new Customer[customerThreads]; //
Thread cThread[] = new Thread[customerThreads]; //
for (int i= 0; i < customerThreads; i++)
{
thr[i]= new Customer(i);
cThread[i] = new Thread(thr [i]);
cThread[i].start();
}
for ( int i = 0; i < customerThreads; i++ )
{
try {
cThread[i].join();
System.out.println("Customer"+i + "joined from main");
}
catch (InterruptedException e)
{
}
}
Teller thr1[] = new Teller[tellerThreads];
Thread tThread[] = new Thread[tellerThreads];
for (int b = 0; b< tellerThreads; b++)
{
thr1[b] = new Teller(B)/>;
tThread[b]= new Thread(thr1 [b]);
tThread[b].start();
}
}
static class Customer implements Runnable
{
private int customerNumber = 0;
private int balance = 0;
Customer(int cn)
{
this.customerNumber = cn;
balance = 1000;
System.out.println("Customer"+ customerNumber + "created");
}
public void run()
{
try
{
System.out.println("I need to deposit");
depositTransaction.acquire();// signal
}
catch(InterruptedException e)
{
Thread.currentThread().interrupt();
e.printStackTrace();
}
withdrawal.release();
System.out.println("I have withdrawn");
}
}
static class Teller implements Runnable
{
private int tellerNumber = 0;
Teller(int tn)
{
this.tellerNumber = tn;
System.out.println("Teller"+ tellerNumber +"created");
}
public void run()
{
try
{
System.out.println("You wanna withdrawal?");
withdrawal.acquire();
}
catch(InterruptedException e)
{
Thread.currentThread().interrupt();
}
depositTransaction.release();
System.out.println("Deposit is complete");
}
}
}[/code]
Here is a program that uses a semaphore to play ping pong. It is very similar to what you need for your goal. This program has one thread that will print PING, and the other prints PONG. It uses a semaphore to ensure that PING is printed first, then PONG, then PING and so on.
Notice how this program uses two semaphores, and that it starts both semaphores at zero. This means that when the threads call acquire() on it, they will block. You have been using the value of one, which means that neither thread would block and that both would rush ahead.
Now that all threads have blocked, we need to get one of them to start. We send a 'release()' signal to the semaphore that the thread that we want to start up on. That will increment the semaphore by one, and the thread blocked in acquire() will wake up and decrement it again before proceeding with its all important job of printing PING or PONG.
Remember the following about semaphores:
A semaphore contains an integer value (called a permit count)
acquire() will block until the integer value is greater than zero; when greater than zero the count will be decremented by one before exiting
release() never blocks. It only ever increments the integer value by one, and as a side effect wakes up any method that were blocked in a call to acquire().
Thus for a game of ping pong to work: (ascii art below scrolls to the right)
s1=0 -- release() --> s1=1 s1=0
s2=0 s2=0 s2=1
thread1=blocked thread1 runs -- calls s2.release() --> thread1 blocked
thread2=blocked thread2=blocked thread2 runs
Notice how the values of s1 and s2 oscilate between 0 and 1, but we do not allow them both to have the value of 1 at the same time. If they were ever to both equal 1, then both thread1 and thread2 would be able to run at the same time. Which would be known as a race condition, as the order of their execution would be unpredictable.
public class PingPong {
public static void main( String[] args ) throws InterruptedException {
final Semaphore s1 = new Semaphore(0);
final Semaphore s2 = new Semaphore(0);
final AtomicInteger countDown = new AtomicInteger( 10 );
Thread threadA = new Thread() {
public void run() {
try {
System.out.println("threadA started");
while (countDown.get() > 0) {
s1.acquire();
System.out.println( "PING" );
s2.release();
countDown.decrementAndGet();
}
} catch ( InterruptedException e ) {
e.printStackTrace();
}
System.out.println("threadA finished");
}
};
Thread threadB = new Thread() {
public void run() {
try {
System.out.println("threadB started");
while (countDown.get() > 0) {
s2.acquire();
System.out.println( "PONG" );
s1.release();
countDown.decrementAndGet();
}
} catch ( InterruptedException e ) {
e.printStackTrace();
}
System.out.println("threadb finished");
}
};
threadA.start();
threadB.start();
s1.release();
}
}
You are not using semaphores correctly for what you want to do. As I get it, you want to start the customer thread, then block until the teller threads finishes then finish the customer thread.
Right now your semaphore do close to nothing. They will prevent multiple customer threads from running at the same time, but within your acquire / release block, nothing happens.
If you want to synchronize between customer and teller, both classes need to use the same Semaphore
What I would suggest is this :
remove the join operation for now
create the depositTransaction semaphore with count 0, so the first acquire will block.
Start a customer thread
The thread will block waiting for a deposit
Start a teller thread
make the deposit and release the depositTransaction semaphore
the customer thread will unblock
you can now join both threads
Edit :
I don't think that your idea of adding tons of semaphore for every action is a good idea. You will end up with complex locking and deadlocks all over the place. What I would suggest is to limit the number of semaphore and implement messages between the threads. The semaphore will tell the other one (Client tells Teller and vice-versa) to check the messages after pushing one.
Start customer thread
push message that customer is waiting
signal for new customer request
wait for teller signal
Start teller thread
acquire sem for new customer request
check message
do stuff
signal customer that stuff is done
messages will then be "withdrawal customer 0" or any other action you want to implement
Would suggest you to look at one of the standard examples and rework your code. Semaphore is very easy to use and all we need to do is acquire the lock when a thread accesses the shared resource and release the lock when it it is done.
There is nice example with a producer and a consumer thread protecting a shared resource here.
Semaphore Example with a Producer and Consumer thread

Thread Synchronization - Synchronizing three threads to print 012012012012..... not working

I am trying to synchronize three threads to print 012012012012.... but it is not working correctly. Each thread is assigned a number which it prints when it receives a signal from main thread. There is something wrong with the following program which I am not able to catch.
public class Application {
public static void main(String[] args) {
int totalThreads = 3;
Thread[] threads = new Thread[totalThreads];
for (int i = 0; i < threads.length; i++) {
threads[i] = new MyThread(i);
threads[i].start();
}
int threadIndex = 0;
while (true) {
synchronized(threads[threadIndex]) {
threads[threadIndex].notify();
}
threadIndex++;
if (threadIndex == totalThreads) {
threadIndex = 0;
}
}
}
}
class MyThread extends Thread {
private int i;
public MyThread(int i) {
this.i = i;
}
#Override
public void run() {
while (true) {
synchronized(this) {
waitForSignal();
System.out.println(i);
}
}
}
private void waitForSignal() {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
You need more coordination. the notify call does not immediately wake up the thread and force it to proceed. Instead, think of notify as sending an email to the thread to let it know that it can proceed. Imagine if you wanted your 3 friends to call you in order. You sent friend 1 an email to call you, waited one second, sent an email to friend 2, waited a second, and sent an email to friend 3. do you think you'd get called in that exact order?
one way to add more coordination would be to have some shared state which indicates whose turn it is. if all your friends could see your house, you could put a number on the outside of the house indicating whose turn it was to call. each friend would wait until they saw their number, and then call.
Here's your problem:
int threadIndex = 0;
while (true) {
synchronized(threads[threadIndex]) {
threads[threadIndex].notify();
}
threadIndex++;
if (threadIndex == totalThreads) {
threadIndex = 0;
}
}
The main thread notifies all threads in the right order. However, your threads are working independently. They may or may not get scheduled at a specific point in time. So the end result may be, that thread 2 is reaching the wait/print lock before thread 1 before thread 0. The final order is not determined by you sending the notifications, but (in essence) by the scheduler.
The solution is to change it this way:
the main thread notifies exactly one thread: thread 0
every thread does his work and when done, notifies the next thread in line
obviously the last thread has to notify thread 0 again.
Another possible solution: In the main thread, you can wait immediately after having notified a thread (in the same synchronized block), like this:
synchronized (threads[threadIndex])
{
threads[threadIndex].notify();
threads[threadIndex].wait(); // try/catch here
}
And in the run method of the thread, you can use notifyAll to wake up the main thread after the thread finished its work:
synchronized (this)
{
waitForSignal();
System.out.println(i);
notifyAll();
}
More sophisticated solutions would involve classes from the java.util.concurrent.locks package.
package threads;
import java.util.concurrent.Semaphore;
public class ZeroEvenOddPrinter {
class Runner extends Thread{
Semaphore prev;
Semaphore next;
int num = 0;
public Runner(Semaphore prev,Semaphore next,int num){
this.prev = prev;
this.next = next;
this.num = num;
}
#Override
public void run(){
while (true) {
try {
Thread.sleep(100);
prev.acquire();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (num == 0)
System.out.println(0);
else {
System.out.println(num);
num = num + 2;
}
next.release();
}
}
}
static public void main(String args[]) throws InterruptedException{
Semaphore sem1 = new Semaphore(1);
Semaphore sem2 = new Semaphore(1);
Semaphore sem3 = new Semaphore(1);
ZeroEvenOddPrinter zeo = new ZeroEvenOddPrinter();
Runner t1 = zeo.new Runner(sem1,sem2,0);
Runner t2 = zeo.new Runner(sem2,sem3,1);
Runner t3 = zeo.new Runner(sem3,sem1,2);
sem1.acquire();
sem2.acquire();
sem3.acquire();
t1.start();
t2.start();
t3.start();
sem1.release();
}
}
Here i am using semaphores as triggers for all the three threads. Initially all threads will be blocked on sem1,sem2,sem3. Then i will release the sem1 and first thread will execute then it will release the second thread and so on... The best part is you extend this logic to n number of threads. Good Luck!!!

How to join one thread with other in java?

I have one main thread that starts 10 other threads. I want that the main thread will be finished only after all other threads stopped. So should I call join() on other 10 threads before starting or after starting them. For instance:
// in the main() method of Main thread
Thread [] threads = new Thread[10];
for(int i = 0; i < 10; i++) {
// ParserThread() is a runnable thread
threads[i] = new Thread(new ParserThread());
threads[i].join();
threads[i].start();
}
System.out.println("All threads have been finished"); // line no. 9
So as in the above example, should i call join() before start() or after start().
Will the control returns to line no. 9 only after all the threads have finished.
When the run method of any thread has been executed, then will that thread die or remain alive. If it will, the how to die all the threads when their run method has finished means when the control returns to line no. 9
Calling join() on a thread only makes sense after the thread is started. The caller of join() will stop and wait until the other thread finishes what it's doing. So you may want to do this:
// in the main() method of Main thread
Thread [] threads = new Thread[10];
for(int i = 0; i < 10; i++) {
// ParserThread() is a runnable thread
threads[i] = new Thread(new ParserThread());
threads[i].start();
}
System.out.println("All threads have been started");
for(int i = 0; i < 10; i++) {
threads[i].join();
}
System.out.println("All threads have been finished");
I recommend against using the low-level Thread constructs like join(), and instead using the higher-level stuff in java.util.concurrent, like CyclicBarrier:
A synchronization aid that allows a
set of threads to all wait for each
other to reach a common barrier point.
CyclicBarriers are useful in programs
involving a fixed sized party of
threads that must occasionally wait
for each other. The barrier is called
cyclic because it can be re-used after
the waiting threads are released.
The usage is much more obvious that Thread.join(), and much less prone to weird bugs.
Instead of writing your own code, you code use a ThreadPoolExecutor to do what you need:
ThreadPoolExecutor executor = new ThreadPoolExecutor(0, 10, 2, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>());
for (int i = 0; i < 10; i++)
executor.execute(new ParserThread());
try {
executor.shutdown();
executor.awaitTermination(10, TimeUnit.MINUTES);
} catch (final InterruptedException e) {
// handle
}
This way, you could easily use less threads to do more tasks if you wish - without changing the code.
you should first start all the thread, then start joining them. Join will return direct if called before the thread is start.
Case can be that you want to join group of threads. See javadoc for
http://download.oracle.com/javase/1.5.0/docs/api/java/util/concurrent/ExecutorCompletionService.html
void solve(Executor e,
Collection<Callable<Result>> solvers)
throws InterruptedException, ExecutionException {
CompletionService<Result> ecs
= new ExecutorCompletionService<Result>(e);
for (Callable<Result> s : solvers)
ecs.submit(s);
int n = solvers.size();
for (int i = 0; i < n; ++i) {
Result r = ecs.take().get();
if (r != null)
use(r);
}
}
For trivial scenarios (one thread), Thread.join() is enough.

Categories

Resources