I create a pool of threads with an Executors.newFixedThreadPool, but after a time I noticed that some of them stoped to answer (call this method below).
They was destroyed? I doing synchonization and the system continues when all threads set that finished the task, but with this, the system enter in deadlock.
They was destroyed? What can I do to prevent or handle this?
//this is the method that threads call when finish the work
synchronized void setTaskFinish(){
System.out.println(Thread.currentThread().getName() + " finishing the work.");
finishedThreads++;
System.out.println(finishedThreads +" finished the work.");
if(finishedThreads == numberThreads){
finishedThreads = 0;
this.notify();
}
}
//this is the method that creates the thread
//I dont know much about this executors yet, so I think it have errors
public void execute(int numberThreads) {
for (int i = 0; i < numberThreads; i++) {
crawlers.add(new SlaveCrawler());
}
ExecutorService threadExecutor = Executors.newFixedThreadPool(numberThreads);
for (int i = 0, n = crawlers.size(); i < n; i++) {
threadExecutor.execute((Runnable) crawlers.get(i));
}
threadExecutor.shutdown();
}
EDIT: I changed entirely my logic. I have not done much testing, but everything seems ok now. Maybe it was something wrong in my old logic.
The executor won't destroy threads that are busy executing your tasks. If you assigned 60 tasks, and only 55 "complete" (more precisely, your setTaskFinish() method is only invoked 55 times), it could be an exception terminating your task prematurely. Deadlock is another possibility, but not the first I would examine.
What happens when your task throws an unchecked exception like RuntimeException? Does it call setTaskFinish() from a finally block? Why are you managing concurrency using synchronized instead of an AtomicInteger?
Related
I'm wondering whether there is any advantage to keeping the same threads over the course of the execution of an object, rather than re-using the same Thread objects. I have an object for which a single (frequently used) method is parallelized using local Thread variables, such that every time the method is called, new Threads (and Runnables) are instantiated. Because the method is called so frequently, a single execution may instantiate upwards of a hundred thousand Thread objects, even though there are never more than a few (~4-6) active at any given time.
Following is a cut down example of how this method is currently implemented, to give a sense of what I mean. For reference, n is of course the pre-determined number of threads to use, whereas this.dataStructure is a (thread-safe) Map which serves as the input to the computation, as well as being modified by the computation. There are other inputs involved, but as they are not relevant to this question, I've omitted their usage. I've also omitted exception handling for the same reason.
Runnable[] tasks = new Runnable[n];
Thread[] threads = new Thread[n];
ArrayBlockingQueue<MyObject> inputs = new ArrayBlockingQueue<>(this.dataStructure.size());
inputs.addAll(this.dataStructure.values());
for (int i = 0; i < n; i++) {
tasks[i] = () -> {
while (true) {
MyObject input = inputs.poll(1L, TimeUnit.MICROSECONDS);
if (input == null) return;
// run computations over this.dataStructure
}
};
threads[i] = new Thread(tasks[i]);
threads[i].start();
}
for (int i = 0; i < n; i++)
threads[i].join();
Because these Threads (and their runnables) always execute the same way using a single ArrayBlockingQueue as input, an alternative to this would be to just "refill the queue" every time the method is called and just re-start the same Threads. This is easily implemented, but I'm unsure as to whether it would make any difference one way or the other. I'm not too familiar with concurrency, so any help is appreciated.
PS.: If there is a more elegant way to handle the polling, that would also be helpful.
It is not possible to start a Thread more than once, but conceptually, the answer to your question is yes.
This is normally accomplished with a thread pool. A thread pool is a set of Threads which rarely actually terminate. Instead, an application is passes its task to the thread pool, which picks a Thread in which to run it. The thread pool then decides whether the Thread should be terminated or reused after the task completes.
Java has some classes which make use of thread pools quite easy: ExecutorService and CompletableFuture.
ExecutorService usage typically looks like this:
ExecutorService executor = Executors.newCachedThreadPool();
for (int i = 0; i < n; i++) {
tasks[i] = () -> {
while (true) {
MyObject input = inputs.poll(1L, TimeUnit.MICROSECONDS);
if (input == null) return;
// run computations over this.dataStructure
}
};
executor.submit(tasks[i]);
}
// Doesn't interrupt or halt any tasks. Will wait for them all to finish
// before terminating its threads.
executor.shutdown();
executor.awaitTermination(Long.MAX_VALUE, TimeUnit.DAYS);
Executors has other methods which can create thread pools, like newFixedThreadPool() and newWorkStealingPool(). You can decide for yourself which one best suits your needs.
CompletableFuture use might look like this:
Runnable[] tasks = new Runnable[n];
CompletableFuture<?>[] futures = new CompletableFuture<?>[n];
for (int i = 0; i < n; i++) {
tasks[i] = () -> {
while (true) {
MyObject input = inputs.poll(1L, TimeUnit.MICROSECONDS);
if (input == null) return;
// run computations over this.dataStructure
}
};
futures[i] = CompletableFuture.runAsync(tasks[i]);
}
CompletableFuture.allOf(futures).get();
The disadvantage of CompletableFuture is that the tasks cannot be canceled or interrupted. (Calling cancel will mark the task as completing with an exception instead of completing successfully, but the task will not be interrupted.)
Per definition, you cannot restart a thread. According to the documentation:
It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution.
Nevertheless a thread is a valuable resource, and there are implementations to reuse threads. Have a look at the Java Tutorial about Executors.
Although this topic has been discussed broadly in other posts I want to present my use case and clarify .So apologies if I am wasting anyone's time. I have the following runnable implementation. Basically infinitely running thread unless java.lang.Error gets thrown by the business logic.
public void run (){
while(true){
try{
//business logic
}catch(Exception ex){
}
}
}
I have about 30 of the above threads started from ExecutorService.
private final ExecutorService normalPriorityExecutorService = Executors.newFixedThreadPool(30);
for(int i=0;i<30;i++) {
normalPriorityExecutorService.submit(//Above Runnable);
}
I want to check and kill the JVM process if the thread count becomes zero on this Executor Service.
if (normalPriorityExecutorService instanceof ThreadPoolExecutor && ((ThreadPoolExecutor) normalPriorityExecutorService).getActiveCount() ==0) {
log.error("No Normal Priority response listeners available. Shutting down App!");
System.exit(1);
}
From my reading since these runnable threads are infinitely running under normal circumstances I will have 30 of them active unless they get killed by runtime Errors.
Question is using getActiveCount() the right approach for my use case ? By the way, when I tried using getPoolSize() instead of getActiveCount(), I did not get the right behavior while testing (I forcefully threw an error to kill a specific thread) and the poolSize still remained thirty.
Since you never use the thread pool as a pool, using a thread pool is overkill. Just create a thread group and start your threads.
private final ThreadGroup normalPriorityThreadGroup = new ThreadGroup("NormalPriority");
for (int i = 0; i < 30; i++) {
new Thread(this.normalPriorityThreadGroup, runnable, "NormalPriority-" + 1).start();
}
if (this.normalPriorityThreadGroup.activeCount() == 0) {
log.error("No Normal Priority response listeners available. Shutting down App!");
System.exit(1);
}
I'm learning multithreading. Can anyone tell why here the output is always 100, even though there are two threads which are doing 100 increments?
public class App {
public static int counter = 0;
public static void process() {
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 100; ++i) {
++counter;
}
}
});
Thread thread2 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 100; ++i) {
++counter;
}
}
});
thread1.start();
thread2.start();
}
public static void main(String[] args) {
process();
System.out.println(counter);
}
}
The output is 100.
You're only starting the threads, not waiting for them to complete before you print the result. When I run your code, the output is 0, not 100.
You can wait for the threads with
thread1.join();
thread2.join();
(at the end of the process() method). When I add those, I get 200 as output. (Note that Thread.join() throws an InterruptedException, so you have to catch or declare this exception.)
But I'm 'lucky' to get 200 as output, since the actual behaviour is undefined as Stephen C notes. The reason why is one of the main pitfalls of multithreading: your code is not thread safe.
Basically: ++counter is shorthand for
read the value of counter
add 1
write the value of counter
If thread B does step 1 while thread A hasn't finished step 3 yet, it will try to write the same result as thread A, so you'll miss an increment.
One of the ways to solve this is using AtomicInteger, e.g.
public static AtomicInteger counter = new AtomicInteger(0);
...
Thread thread1 = new Thread(new Runnable() {
#Override
public void run() {
for (int i = 0; i < 100; ++i) {
counter.incrementAndGet();
}
}
});
Can anyone tell why here the output is always 100, even though there are two threads which are doing 100 increments?
The reason is that you have two threads writing a shared variable and a third reading, all without any synchronization. According to the Java Memory Model, this means that the actual behavior of your example is unspecified.
In reality, your main thread is (probably) printing the output before the second thread starts. (And apparently on some platforms, it prints it before the first one starts. Or maybe, it is seeing a stale value for counter. It is a bit hard to tell. But this is all within the meaning of unspecified)
Apparently, adding join calls before printing the results appears to fix the problem, but I think that is really by luck1. If you changed 100 to a large enough number, I suspect that you would find that incorrect counter values would be printed once again.
Another answer suggests using volatile. This isn't a solution. While a read operation following a write operation on a volatile is guaranteed to give the latest value written, that value may be a value written by another thread. In fact the counter++ expression is an atomic read followed by an atomic write ... but the sequence is not always atomic. If two or more threads do this simultaneously on the same variable, they are liable to lose increments.
The correct solutions to this are to either using an AtomicInteger, or to perform the counter++ operations inside a synchronized block; e.g.
for (int i = 0; i < 100; ++i) {
synchronized(App.class) {
++counter;
}
}
Then it makes no difference that the two threads may or may not be executed in parallel.
1 - What I think happens is that the first thread finishes before the second thread starts. Starting a new thread takes a significant length of time.
In Your case, There are three threads are going to execute: one main, thread1 and thread2. All these three threads are not synchronised and in this case Poor counter variable behaviour will not be specific and particular.
These kind of Problem called as Race Conditions.
Case1: If i add only one simple print statement before counter print like:
process();
System.out.println("counter value:");
System.out.println(counter);
in this situation scenario will be different. and there are lot more..
So in these type of cases, according to your requirement modification will happen.
If you want to execute one thread at time go for Thread join like:
thread1.join();
thread2.join();
join() is a Thread class method and non static method so it will always apply on thread object so apply join after thread start.
If you want to read about Multi threading in java please follow; https://docs.oracle.com/cd/E19455-01/806-5257/6je9h032e/index.html
You are checking the result before threads are done.
thread1.start();
thread2.start();
try{
thread1.join();
thread2.join();
}
catch(InterruptedException e){}
And make counter variable volatile.
I'm trying to start a thread in a for-loop. This task should only wait for a second (Thread.sleep()), so every time the loop starts over again, a new thread is started and it should cause the code after the thread to wait until it is executed.
public void count()
{
for(int i = 29; i>=0; i--)
{
Thread t1;
t1 = new Thread(new TimerClass());
t1.start();
String s = String.valueOf(i);
jLabel6.setText(s);
System.out.println(s);
}
}
public class TimerClass implements Runnable{
#Override
public void run()
{
try{
Thread.sleep(1000);
System.out.println("Timer");
} catch(InterruptedException e)
{
}
}
}
As you can see, I implemented in both methods System.out.println() to check if they are actually executed. I get this:
29
28
27
26
...//25 - 3
2
1
0
Timer
Timer
Timer
//in all 29 times Timer
So it should be 29, Timer, 28, Timer and so on, but it isn't.
Does anyone know what's wrong with the code?
Thanks a lot.
Your main loop that is starting the thread is likely dominating the CPU, so it finishes doing its entire loop and only then do the threads get a chance to go.
In fact, given that all of your threads sleep for an entire second and you're only looping 29 times, you're guaranteed that your loop will finish (and print all of the numbers) before your threads do. Add a sleep to your main loop if you want the threads to print - remember, the main loop doesn't stop when you start a thread.
You can join a thread to the main thread so first your thread will finished then main thread
public void count()
{
for(int i = 29; i>=0; i--)
{
Thread t1;
t1 = new Thread(new TimerClass());
t1.start();
t1.join();
String s = String.valueOf(i);
jLabel6.setText(s);
System.out.println(s);
}
}
Here is my code for spawning 2 threads or one thread depends on arrayList size but in my case this threads are doing much more complex tasks then just waiting 1 sec
for (int i = 0; i < array.size(); i += 2) {
Thread t1 = null;
Thread t2 = null;
if (i < array.size() - 1 && array.size() > 1) {
t1 = new Thread(array.get(i));
t2 = new Thread(array.get(i + 1));
t1.start();
t2.start();
}
else {
t2 = new Thread(array.get(i));
t2.start();
}
if (t1 != null)
t1.join();
if (t2 != null)
t2.join();
}
In my code I populate arrayList with Objects that Implements Runnable interface.
Even if you sleep the thread for 1ms, your results would be the same. If you can manage the thread to sleep for the time less than it takes to print the results, your result could be as expected. Here is my code where I have put the time of 1 ms but yet the results are the same.
public class MultiThreading implements Runnable
{
public void run()
{
try
{
Thread.sleep(1);
System.out.println("Timer");
}
catch(Exception e)
{
}
}
public static void main(String [] args)
{
for(int i = 29; i>=0; i--)
{
Thread t1;
t1 = new Thread(new MultiThreading());
t1.start();
String s = String.valueOf(i);
System.out.println(s);
}
}
}
If you comment out the Thread.sleep(1) method, then your results are as you expected.
Delay is much enough to let the for loop in count() to finish before is can print 'timer' from thread.
What is happening is that the thread you started starts executing and immediately goes to sleep. In the meantime, your loop just keeps running. As the whole point of threads is that they run asynchronously, I don't really understand why you think your main loop should be waiting for it to finish sleeping. The thread has started running and is now running independently of the main loop.
If you want to wait for the thread you just started to finish (in which case, you might as well use a method), then use one of the synchronisation primitives, i.e. Thread.wait().
What you actually want to do is block your main thread while another thread is running. Please don't use Thread#sleep statements, as these are unreliable in order to "make your application work". What you want to use instead is Thread#join. See dharr his code for an example.
Also, it's better to use Executors and ExecutorServices when creating threads or running async tasks.
Threads are interesting. Think of a virtual thread as a physical thread. There are many threads on the clothes you're wearing, all working at the same time to hold your shirt together. In virtual terms what Thread.start() does is start a thread on a different strand WHILE the following code continues to execute, (i.e. Two Threads work simultaneously like 2 runners run next to each other). Consider putting a break point right after Thread.start(). You'll understand.
For your desired effect, just put a Thread.sleep() in the main loop. This will cause an output of
29
Timer
28
Timer
// etc.
Hope this helped.
Jarod.
Another analogy to the threads in a shirt:
Think of threads as coworkers to your main programm (which is a thread itself). If you start a thread, you hand some work to this coworker. This coworker goes back to his office to work on this task. You also continue to do your task.
This is why the numbers will appear before the first thread/coworker will output anythig. You finished your task (handing out work to other coworkers) before he finished his.
If you want to give out some work and then wait for it to be finished, use t1.join() as suggested by others. But if you do this, it is senseless to create new Threads, because you don't (seem) to want to process something in parallel (with many coworkers) but in a specific order - you can just du it yourself.
I was simply exploring the java.util.concurrent package.
I learnt that the class 'Future' has a method boolean cancel(boolean mayInterruptIfRunning)
Please find attached the test code I wrote :
package com.java.util.concurrent;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
public class FutureTester {
/**
* #param args
* #throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
int poolCnt = 1;
Callable<NumberPrinter> numberPrinter = null;
ScheduledThreadPoolExecutor schPool = new ScheduledThreadPoolExecutor(
poolCnt);
ScheduledFuture<NumberPrinter>[] numPrinterFutures = new ScheduledFuture[poolCnt];
FutureTask<NumberPrinter>[] futureTask = new FutureTask[poolCnt];
for (int i = 0; i < poolCnt; i++) {
numberPrinter = new NumberPrinter();
futureTask[i] = new FutureTask<NumberPrinter>(numberPrinter);
/*
* numPrinterFutures[i] = (ScheduledFuture<NumberPrinter>) schPool
* .schedule(futureTask[i], 0, TimeUnit.MILLISECONDS);
*/
numPrinterFutures[i] = (ScheduledFuture<NumberPrinter>) schPool
.submit(futureTask[i]);
}
//Thread.sleep(30);
if (numPrinterFutures.length > 0) {
System.out.println("Task completed ? "
+ numPrinterFutures[0].isDone());
System.out.println("Task cancelled ? "
+ numPrinterFutures[0].cancel(true));
System.out.println("Is task cancelled ? "
+ numPrinterFutures[0].isCancelled());
}
}
}
class NumberPrinter implements Callable<NumberPrinter> {
private int counter = 10;
#Override
public NumberPrinter call() throws Exception {
// TODO Auto-generated method stub
while (counter > 0) {
if (Thread.interrupted()) {/*OUCH !!!*/
return null;
}
System.out.println("counter = " + (counter--));
}
return this;
}
}
Intially,I assumed that cancelling a task will also stop the execution of a running thread(the 'OUCH' part NOT included).But I got the output as follows :
counter = 10
Task completed ? false
counter = 9
Task cancelled ? true
counter = 8
Is task cancelled ? true
counter = 7
counter = 6
counter = 5
counter = 4
counter = 3
counter = 2
counter = 1
On further reading on stackoverflow itself,it was said that
The 'cancel' method can only stop the 'unstarted' jobs(which contradicts with the api description of the method)
The cancel method simply interrupts the running thread which then
must return from the run() method
Hence,I included the 'OUCH' part - a while loop checking for interruption;the output was as follows :
Task completed ? false
counter = 10
Task cancelled ? true
Is task cancelled ? true
QUESTION :
If one is supposed to write something analogous to the 'OUCH' part to stop the running thread,what is the utility/value of the cancel method. How does wrapping a Callable in a FutureTask help if the Thread can't be stopped by cancel? What is the design/conceptual/logical part that I am overlooking?
How does wrapping a Callable in a FutureTask help if the Thread can't be stopped by cancel?
You want to cancel the task, not the thread running it. Using cancel(true) prevents the task from starting (but doesn't remove it from the queue) and interrupts the thread if the task has started. The Task can ignore the interrupt, but there is no clean way of killing a thread without killing the whole process.
The problem that you are overlooking is that only cooperating threads can be stopped safely in Java.
Indeed, if you look at the Thread API, you will notice that there are some methods called destroy, pause, stop, and resume that were deprecated in Java 1.1. The reason that they were deprecated is that the Java designers realized that they generally can't be used safely. The reasons are explained in the note "Why are Thread.stop, Thread.suspend and Thread.resume Deprecated?".
The problem is inherent in the Java threading model, and could only be avoided by curtailing the ability of one thread to interact with objects used by other threads. There is a JSR that specifies one one way of doing this ... Isolates ... but no mainstream JVMs implement these APIs to my knowledge.
So bringing this back to your question, the usefulness of Future.cancel is that it solves the subset of the problem that can be solved in the context of futures.
Invoking cancel(true) will prevent the Future from executing if not already run and will be interrupted if currently running. At this point, the burden to cancel the Future is put on the developer.
Since it is a thread pool it wouldn't make sense to stop the thread (though it rarely if ever makes sense to stop a thread). The cancel/interrupt will not cause the thread to exit from its run method. After the execution of your Callable's call method it will simply pull the next item off the work queue and process that.
The utility of the cancel method is simply to signal the executing thread that some process want's that Callable to stop - not the thread - so you will have to handle the stopping of the Callable yourself.
Suppose, that the code that runs as part of your future does not support cooperative cancellation or interruption. Then cancelling an unstarted task is the best thing you can possibly do. That is why this method exists.
In general I think of cancellation as strictly cooperative. Just cancelling some piece of code by force can lead to corrupted state.