Extend Thread to test proper termination with join? - java

Java Concurrency In Practice, 12.1.2. Testing Blocking Operations:
void testTakeBlocksWhenEmpty() {
final BoundedBuffer<Integer> bb = new BoundedBuffer<Integer>(10);
Thread taker = new Thread() {
public void run() {
try {
int unused = bb.take();
fail(); // if we get here, it’s an error
} catch (InterruptedException success) { }
}
};
try {
taker.start();
Thread.sleep(LOCKUP_DETECT_TIMEOUT);
taker.interrupt();
taker.join(LOCKUP_DETECT_TIMEOUT);
assertFalse(taker.isAlive());
} catch (Exception unexpected) {
fail();
}
}
This is one of the few cases in which it is appropriate to subclass
Thread explicitly instead of using a Runnable in a pool: in order to
test proper termination with join. The same approach can be used to
test that the taker thread unblocks after an element is placed in the
queue by the main thread.
But I don't see how extending Thread helps with testing that. For me it seems that the same test could be done with passing Runnable to Thread. Can somebody explain that?

This is one of the few cases in which it is appropriate to subclass
Thread explicitly instead of using a Runnable in a pool: in order to
test proper termination with join.
In other words that approach lets you a chance to interrupt the test thread and join it to make sure it has been terminated properly. You can't handle threads in that way if you use, for example - ThreadPoolExecutor class.
Also, it is OK to create a new thread, initiating it with Runnable, like Thread taker = new Thread(() -> {...});. Remember that the book was written about 8 years ago, and creating Runnable instead of subclass of Thread would make that example a bit longer.

Related

Main thread to wait two parallel threads children java

first what i am trying to do:
During the main thread execution i want to pause the main thread and start two parallel threads. As soon as both this parallel threads terminate, i'd like to start again with the main thread.
What i tried:
...
...
main thread is executing
...
...
CyclicBarrier barrier = new CyclicBarrier(2);
Thread child1 = new Thread(new ThreadBuilderTask(barrier,0));
Thread child2 = new Thread(new ThreadBuilderTask(barrier,1));
child1.start();
child2.start();
/* Now i'm expecting that child1 and child2 are running in parallel calling their fooFunction */
child1.join();
child2.join();
/*Now i'm expecting that main thread will wait for child1and also for child2 (that are running in parallel).*/
... main thread starts again after both child1 and child2 finished (reached the await of the barrier)
... (break point set here, never reached)
...
Thread builder custom class
public class ThreadBuilderTask implements Runnable{
private CyclicBarrier barrier;
private int index;
...setters and getters..
#Override
public void run() {
fooFunction(this.getIndex());
try {
this.getBarrier().await();
} catch (InterruptedException | BrokenBarrierException e) {
return;
}
}
public ThreadBuilderTask(CyclicBarrier barrier,int index){
this.barrier = barrier;
this.index = index;
}
public fooFunction(int index){
//Something taking some seconds to execute
}
It's not clear what is happening here but it is definetely not working. As soon as i call join everything stops and the main thread never restart. (I put a breakpoint after the joins to see when the main thread restarts).
Maybe there is a bit of confusion with these concepts and also i'm not sure if i need to use both the barrier and the joins or simply one of those techniques.
Thanks
Davide
As mentioned in the comments I'd also suggest to use CompletableFuture. A very basic example of your described requirements could look like this:
final Runnable runnable1 = ...;
final Runnable runnable2 = ...;
CompletableFuture<Void> future1 = CompletableFuture.runAsync(runnable1);
CompletableFuture<Void> future2 = CompletableFuture.runAsync(runnable2);
CompletableFuture.allOf(future1, future2).get(); // waits for both runnables to finish
You might want to add more/some exception handling to this example. But it should give an idea how this might work.
You may consider to use Java CompletableFuture to achieve the objective.
Using its functions like supplyAsync or runAsync you may start child threads and join their respective result in the end. Or you can simply let the main thread wait until the subsequent threads completes.
Recently I managed to implement a sample scatter-gather function using the same class.
Check Java Doc for more offerings and to find best available function: https://docs.oracle.com/javase/8/docs/api/java/util/concurrent/CompletableFuture.html

Not Getting expected result in multi-threaded program

I'm not getting expected result for below program, I was expecting both producer and consumer method should execute in some sequence, but for some reason only producer method is getting executed.
I have two question here :
I'm not able to understand this behaviour.
Joining both thread together in last line of main method is working properly, I'm not able to understand difference between both.
public class ProducerConsumer {
List<Integer> data = new ArrayList<>();
synchronized void produce() throws InterruptedException {
for (int i = 0; i < 10; i++) {
System.out.println("Producing");
data.add(i);
}
wait();
}
synchronized void consume() throws InterruptedException {
System.out.println("Consuming");
data.clear();
notify();
}
public static void main(String[] args) throws InterruptedException {
ProducerConsumer pc = new ProducerConsumer();
Runnable r2 = ()-> {
try {
pc.produce();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread1 = new Thread(r2);
thread1.start();
thread1.join();
Runnable r1 = () -> {
try {
pc.consume();
} catch (InterruptedException e) {
e.printStackTrace();
}
};
Thread thread = new Thread(r1);
thread.start();
thread.join();
}
Output :
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
Producing
The produce() method ends with wait(). So it blocks until some thread notifies it.
The only thread that does that is the consumer thread. But the consumer thread is started by the main method only after the producer thread has ended. And it can't end until it's been notified. So you have a deadlock.
If you join() only after the two threads are started, then the consumer thread can start without having to wait for the producer thread to be finished. That still doesn't make the program correct since
you have no guarantee that the producer thread will execute first
calling wait() at then end is useless
calling wait() out of a loop checking for a condition is incorrect
if you want methods to execute in sequence, using threads is useless. You can do everything from the main thread.
1) A notify() call does not do anything at all. Unless some other thread is already waiting to be notified.
It's up to you to guarantee that any time one of your threads calls wait(), some other thread will notify() the same object some time after the wait() has begun.
Oracle's Guarded Blocks Tutorial does a pretty good job of explaining exactly how o.wait() and o.notify() work, and it explains how to establish that guarantee.
2) There is virtually no reason to do this:
Thread t = new Thread(r);
t.start();
t.join();
Your program will use less CPU, and it will use less memory, and it will accomplish exactly the same thing if you just call r.run() instead. The entire point of threads is to allow different things to happen concurrently, and there is no concurrency if one thread joins a new thread immediately after creating it. The new Thread object is wasted unless you do something like this with it:
Thread t = new Thread(r);
t.start();
doSomethingElseWhileThread_t_isRunning();
t.join();
3) wait() and notify() are a very low-level means of communicating between threads. Your code will be easier to read and understand if you use higher-level synchronization objects that are built on top of wait() and notify() instead of directly
calling them.
A java.util.concurrent.ArrayBlockingQueue instance would be especially well suited to a "producer/consumer" application.

Should i nullify an interrupted thread?

I created a thread like this:
private Thread t = new Thread() {
#Override
public void run() {
try {
while(true) {
// do work
Thread.sleep(1000);
}
} catch (InterruptedException ex) {
}
}
};
t.start();
Then i interrupted it using t.interrupt().
As soon the thread stops and get on sleep() it will interrupt and become unusable, but will it stay on memory?
Do i have to call t = null, or the GC will take care of that?
I'm trying to dynamically interrupt the thread and recreate it when needed (using t = new Thread()), but im not sure if just interrupt() removes the old thread from memory. I've searched but couldn't find this specfic answer.
The Thread class is a proxy for the OS Thread. Before you call start() there is no actual OS thread and after the thread stops it is cleaned up even if you hold on to the Thread object. At this point it just like any other object and it will be cleaned up in the normal way.
Seems you are using this code snippet inside a method thus Thread t becomes local variable and it will be cleared by gc , just make sure you don't use this reference variable further down in the method.

How to wait for all threads to complete

I created some workflow how to wait for all thread which I created. This example works in 99 % of cases but sometimes method waitForAllDone is finished sooner then all thread are completed. I know it because after waitForAllDone I am closing stream which is using created thread so then occurs exception
Caused by: java.io.IOException: Stream closed
my thread start with:
#Override
public void run() {
try {
process();
} finally {
Factory.close(this);
}
}
closing:
protected static void close(final Client client) {
clientCount--;
}
when I creating thread I call this:
public RobWSClient getClient() {
clientCount++;
return new Client();
}
and clientCount variable inside factory:
private static volatile int clientCount = 0;
wait:
public void waitForAllDone() {
try {
while (clientCount > 0) {
Thread.sleep(10);
}
} catch (InterruptedException e) {
LOG.error("Error", e);
}
}
You need to protect the modification and reading of clientCount via synchronized. The main issue is that clientCount-- and clientCount++ are NOT an atomic operation and therefore two threads could execute clientCount-- / clientCount++ and end up with the wrong result.
Simply using volatile as you do above would ONLY work if ALL operations on the field were atomic. Since they are not, you need to use some locking mechanism. As Anton states, AtomicInteger is an excellent choice here. Note that it should be either final or volatile to ensure it is not thread-local.
That being said, the general rule post Java 1.5 is to use a ExecutorService instead of Threads. Using this in conjuction with Guava's Futures class could make waiting for all to complete to be as simple as:
Future<List<?>> future = Futures.successfulAsList(myFutureList);
future.get();
// all processes are complete
Futures.successfulAsList
I'm not sure that the rest of your your code has no issues, but you can't increment volatile variable like this - clientCount++; Use AtomicInteger instead
The best way to wait for threads to terminate, is to use one of the high-level concurrency facilities.
In this case, the easiest way would be to use an ExecutorService.
You would 'offer' a new task to the executor in this way:
...
ExecutorService executor = Executors.newFixedThreadPool(POOL_SIZE);
...
Client client = getClient(); //assuming Client implements runnable
executor.submit(client);
...
public void waitForAllDone() {
executor.awaitTermination(30, TimeUnit.SECOND) ; wait termination of all threads for 30 secs
...
}
In this way, you don't waste valuable CPU cycles in busy waits or sleep/awake cycles.
See ExecutorService docs for details.

Java - Basic Multithreading

I would like to ask basic question about Java threads. Let's consider a producer - consumer scenario. Say there is one producer, and n consumer. Consumer arrive at random time, and once they are served they go away, meaning each consumer runs on its own thread. Should I still use run forever condition for consumer ?
public class Consumer extends Thread {
public void run() {
while (true) {
}
}
}
Won't this keep thread running forever ?
I wouldn't extend Thread, instead I would implement Runnable.
If you want the thread to run forever, I would have it loop forever.
A common alternative is to use
while(!Thread.currentThread().isInterrupted()) {
or
while(!Thread.interrupted()) {
It will, so you might want to do something like
while(beingServed)
{
//check if the customer is done being served (set beingServed to false)
}
This way you'll escaped the loop when it's meant to die.
Why not use a boolean that represents the presence of the Consumer?
public class Consumer extends Thread {
private volatile boolean present;
public Consumer() {
present = true;
}
public void run() {
while (present) {
// Do Stuff
}
}
public void consumerLeft() {
present = false;
}
}
First, you can create for each consumer and after the consumer will finish it's job than the consumer will finish the run function and will die, so no need for infinite loop. however, creating thread for each consumer is not good idea since creation of thread is quite expensive in performance point of view. threads are very expensive resources. In addition, i agree with the answers above that it is better to implement runnable and not to extends thread. extend thread only when you wish to customize your thread.
I strongly suggest you will use thread pool and the consumer will be the runnable object that ran by the thread in the thread pool.
the code should look like this:
public class ConsumerMgr{
int poolSize = 2;
int maxPoolSize = 2;
long keepAliveTime = 10;
ThreadPoolExecutor threadPool = null;
final ArrayBlockingQueue<Runnable> queue = new ArrayBlockingQueue<Runnable>(
5);
public ConsumerMgr()
{
threadPool = new ThreadPoolExecutor(poolSize, maxPoolSize,
keepAliveTime, TimeUnit.SECONDS, queue);
}
public void runTask(Runnable task)
{
// System.out.println("Task count.."+threadPool.getTaskCount() );
// System.out.println("Queue Size before assigning the
// task.."+queue.size() );
threadPool.execute(task);
// System.out.println("Queue Size after assigning the
// task.."+queue.size() );
// System.out.println("Pool Size after assigning the
// task.."+threadPool.getActiveCount() );
// System.out.println("Task count.."+threadPool.getTaskCount() );
System.out.println("Task count.." + queue.size());
}
It is not a good idea to extend Thread (unless you are coding a new kind of thread - ie never).
The best approach is to pass a Runnable to the Thread's constructor, like this:
public class Consumer implements Runnable {
public void run() {
while (true) {
// Do something
}
}
}
new Thread(new Consumer()).start();
In general, while(true) is OK, but you have to handle being interrupted, either by normal wake or by spurious wakeup. There are many examples out there on the web.
I recommend reading Java Concurrency in Practice.
for producer-consumer pattern you better use wait() and notify(). See this tutorial. This is far more efficient than using while(true) loop.
If you want your thread to processes messages until you kill them (or they are killed in some way) inside while (true) there would be some synchronized call to your producer thread (or SynchronizedQueue, or queuing system) which would block until a message becomes available. Once a message is consumed, the loop restarts and waits again.
If you want to manually instantiate a bunch of thread which pull a message from a producer just once then die, don't use while (true).

Categories

Resources