I am storing a bunch of threads objects in an arraylist. I want to be able to start these threads at random. Same thread can be started more than once. Before I start a thread object, I check on whether the thread is alive, and if they have either of NEW or TERMINATED status. This restriction because, I don't want to disturb the 'busy' threads. Now, for NEW threads, this works fine. But for TERMINATED thread, I get an exception.
When a thread ends, shouldn't it go back to being 'new'? Or are threads 'disposable' - like use once and done?
As it says in the documentation for Thread.start(), "It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution."
It is better for you to keep hold of Runnable instances and implement your own logic for keeping track of when the execution of each one of them finishes. Using an Executor is probably the simplest way to run the Runnables.
You should probably be using the awesome stuff provided in java.util.concurrent. Based on your description, ThreadPoolExecutor sounds like a good thing to check out.
This is the way I did it
class GarbageDisposalThread extends Thread {
public void start() {
try {
super.start();
} catch( IllegalThreadStateException e ) {
this.arrayList.remove(this);
this.arrayList.add( new GarbageDisposalThread( this.arrayList ));
}
}
private GarbageDisposalThread() {
}
public GarbageDisposalThread( ArrayList<Whatever> arrayList ) {
this.arrayList = arrayList;
this.start();
}
public void run() {
// whatever the code
}
private ArrayList<Whatever> arrayList = null;
}
that's it!
you can change the code according to your needs :P
Java threads cannot be restarted.
From the javadoc:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
See the Thread.start() javadoc for more information.
There are other ways to accomplish what you are trying to do. For example, you could use new Threads that continue the work that was done in the Thread that has finished execution. You may also want to investigate the java.util.concurrent package.
From another post...
You could use ThreadPoolExecutor, which would allow you to pass in tasks and let the service assign a thread to a task. When the task is finished, the thread goes idle until it gets the next task.
So, you don't restart a thread, but you would redo/resume a task.
Related
I am trying to figure out the solution for a scenario of cancelling a group of threads if one of the Thread finishes the task successfully.
The scenario is like this: Lets say a group of threads are working on a task to find a String in a file and if any of the thread finds the String, the remaining treads should stop execution.
Using 1.5 concurrency we can achieve this, but prior to JDK 1.5 if we want to achieve this kind of scenario, then how can we do that?
For Java 2 Platform, Standard Edition 1.4 SDK or higher you could use exception chaining.
How about just splitting up the thread's task into smaller chunks and checking for a stop condition in the loop?
You could interrupt the threads and in each thread check for the interrupted flag:
public class Job implements Runnable {
#Override
public void run() {
while (!Thread.currentThread().isInterrupted()) {
// perform stuff
}
}
}
In the shutdown-code you call
thread.interrupt();
for each other thread.
The advantage compared to a stop-flag is that your threads will also drop out of any blocking calls.
The good way to stop a thread is to have it periodically check a flag that indicates whether or not it should continue. The java Thread class already has such a facility, called interrupts, that is useful in many scenarios, as bennihepp points out in his answer. See the javadoc for the Thread class and the interrupt() and isInterrupted() methods in particular.
In the following example the runnable class makes sure that all of the instances halt (soon) after one instance finishes. It is worth noting that you should keep your unit of work (one iteration of the loop) small enough.
public class MyRunnable implements Runnable {
private static boolean shouldStop = false;
public void run() {
// allocate required resources
while (!MyRunnable.shouldStop) {
// do work
if (/* some condition to indicate completion */)
MyRunnable.shouldStop = true;
}
// release any allocated resources
}
}
This simple example assumes all threads wrap the same type of a runnable object. Once one sets the shouldStop flag, all others also stop. It would be quite trivial to extend the example to also facilitate interruptions.
Ok.... Let me try to explain this the best I can....
Also: this is for a mod within minecraft.
Okay, so I created a thread object
public static Thread KillThread = new Thread();
Then in the constructor of my main class which is called when the game(Mine craft starts) I have
KillThread = new Thread(new KillAuraThread());
KillAuraThread is the name of the class that is the thread..
So I created a thread now. Is where it's pissing me off
The thread will run for exactly 1 second, and It can not be running multiple times or it will ruin the point of the delaying and threading.
if(KillAura.enabled && !KillThread.isAlive())
{
System.out.println("Go AURA!");
try
{
KillThread.start();
}catch (Exception e)
{
e.printStackTrace();
}
}
That is called every tick within the game where it would send position updates and such.
Now here is where I'm having the problem. Once the thread starts it becomes "alive" and when it ends it is no longer "alive". But can threads only be started once? because after the first run it's no longer working? And ideas? Links?
Yes Threads can only be started once, you cannot reuse a Thread object.
It is never legal to start a thread more than once. In particular, a
thread may not be restarted once it has completed execution. See java.lang.Thread.start()
Regardless of this fact, do not use the Thread.State for thread lifecycle management.
You're right, threads can run only once and it's illegal to start/run a thread more than once. You should consider using a while loop to keep your thread alive.
Instead of directly dealing with Threads, you should be using the classes inside the java.util.concurrent package to schedule a fixed task at regular intervals which is apparently what you're trying to do. Take a look at ThreadPoolExecutor.
I have a Thread which runs my game loop. I want to be able to run this game loop each time I start a new game. But since the threads in Java can only be started once, how can I do this?
Create a new Thread around the same Runnable instance and start that.
Since you want the Thread that runs the game loop to keep running it, you need to code it something like this:
public class GameLoop implements Runnable {
...
public void run() {
while (gameNotFinished) {
// do stuff
}
}
}
If that is not working, then the chances are that the run() method is dying because of an exception that you are not catching / logging, and therefore not noticing.
1. When you say that "you need to run a thread", i means you want to start a sub-task on a separate thread.
2. Now if you mean this certain sub-task, then please prefer to run a new thread.
3. As you said But since the threads in Java can only be started once
This means that when a thread (thread of execution) completes its run() method, then the Thread object associated with it permanently looses its threadness, right....
But if this thread is from a pool, then the pool itself manages the Thread objects and its reused. Try using Executors from java.util.concurrent package.
1) The short answer is precisely what SLaks already said: just "...create a new thread around the same runnable instance and start that."
2) I think you might be confused about the distinction between the everyday meaning of "start", and the semantics of the Java Thread method "start()". This tutorial might help:
http://www.geom.uiuc.edu/~daeron/docs/javaguide/java/threads/states.html
3) Should you wish to re-use the same thread, you can use the methods "wait()" and "resume()":
http://www.javabeginner.com/learn-java/java-threads-tutorial
I have question about the Java threads. Here is my scenario:
I have a thread calling a method that could take while. The thread keeps itself on that method until I get the result. If I send another request to that method in the same way, now there are two threads running (provided the first did not return the result yet). But I want to give the priority to the last thread and don't want to get the results from the previously started threads. So how could I get rid of earlier threads when I do not have a stop method?
The standard design pattern is to use a local variable in the thread that can be set to stop it:
public class MyThread extends Thread {
private volatile boolean running = true;
public void stop() {
running = false;
}
public void run() {
while (running) {
// do your things
}
}
}
This way you can greacefully terminate the thread, i.e. without throwing an InterruptedException.
The best way really depends on what that method does. If it waits on something, chances are an interrupt will result in an InterruptedException which you handle and cleanly exit. If it's doing something busy, it won't:
class Scratchpad {
public static void main(String[] a) {
Thread t = new Thread(new Runnable() {
public void run() {doWork();}
});
t.start();
try {
Thread.sleep(50);
} catch (InterruptedException ie) {}
t.interrupt();
}
private static void doWork() {
for ( long i = 1; i != 0; i *=5 );
}
}
In the case above, the only viable solution really is a flag variable to break out of the loop early on a cancel, ala #inflagranti.
Another option for event-driven architectures is the poison-pill: if your method is waiting on a blocking queue for a new item, then you can have a global constant item called the "poison-pill" that when consumed (dequeued) you kill the thread:
try {
while(true) {
SomeType next = queue.take();
if ( next == POISON_PILL ) {
return;
}
consume(next);
}
} catch //...
EDIT:
It looks like what you really want is an executor service. When you submit a job to an executor service, you get back a Future which you can use to track results and cancel the job.
You can interrupt a Thread, its execution chain will throw an InterruptedException most of the time (see special cases in the documentation).
If you just want to slow down the other thread and not have it exit, you can take some other approach...
For one thing, just like exiting you can have a de-prioritize variable that, when set, puts your thread to sleep for 100ms on each iteration. This would effectively stop it while your other thread searched, then when you re-prioritize it it would go back to full speed.
However, this is a little sloppy. Since you only ever want one thing running but you want to have it remember to process others when the priority one is done, you may want to place your processing into a class with a .process() method that is called repeatedly. When you wish to suspend processing of that request you simply stop calling .process on that object for a while.
In this way you can implement a stack of such objects and your thread would just execute stack.peek().process(); every iteration, so pushing a new, more important task onto the stack would automatically stop any previous task from operating.
This leads to much more flexible scheduling--for instance you could have process() return false if there is nothing for it to do at which point your scheduler might go to the next item on the stack and try its' process() method, giving you some serious multi-tasking ability in a single thread without overtaxing your resources (network, I'm guessing)
There is a setPriority(int) method for Thread. You can set the first thread its priority like this:
Thread t = new Thread(yourRunnable);
t.start();
t.setPriority(Thread.MIN_PRIORITY); // The range goes from 1 to 10, I think
But this won't kill your thread. If you have only two threads using your runnable, then this is a good solution. But if you create threads in a loop and you always sets the priority of the last thread to minimum, you will get a lot of threads.
If this is what is application is going to do, take a look at a ThreadPool. This isn't an existing class in the Java API. You will have create one by yourself.
A ThreadPool is another Thread that manages all your other Threads the way you want. You can set a maximum number of running Threads. And in that ThreadPool, you can implement a system that manages the Thread priority automatically. Eg: You can make that older threads gain more priority, so you can properly end them.
So, if you know how to work with a ThreadPool, it can be very interesting.
According to java.lang.Thread API, you should use interrupt() method and check for isInterrupted() flag while you're doing some time-consuming cancelable operation. This approach allows to deal with different kind of "waiting situations":
1. wait(), join() and sleep() methods will throw InterruptedExcetion after you invoke interrupt() method
2. If thread blocked by java.nio.channels.Selector it will finish selector operation
3. If you're waiting for I/O thread will receive ClosedByInterruptException, but in this case your I/O facility must implement InterruptibleChannel interface.
If it's not possible to interrupt this action in a generic way, you could simply abandon previous thread and get results from a new one. You could do it by means of java.util.concurrent.Future and java.util.concurrent.ExecutorService.
Cosider following code snippet:
public class RequestService<Result> {
private ExecutorService executor = Executors.newFixedThreadPool(3);
private Future<Result> result;
public Future<Result> doRequest(){
if(result !=null){
result.cancel(true);
}
result = executor.submit(new Callable<Result>() {
public Result call() throws Exception {
// do your long-running service call here
}
});
return result;
}
}
Future object here represents a results of service call. If you invoke doRequest method one more time, it attempts to cancel previous task and then try to submit new request. As far as thread pool contain more than one thread, you won't have to wait until previous request is cancelled. New request is submitted immediately and method returns you a new result of request.
exampl:
new Thread(new Runnable() {
public void run() {
while(condition) {
*code that must not be interrupted*
*some more code*
}
}
}).start();
SomeOtherThread.start();
YetAntherThread.start();
How can you ensure that code that must not be interrupted won't be interrupted?
You can't - at least not with normal Java, running on a normal, non-real-time operating system. Even if other threads don't interrupt yours, other processes might well do so. Basically you won't be able to guarantee that you get a CPU all to yourself until you're done. If you want this sort of guarantee you should use something like Java Real-Time System. I don't know enough about it to know whether that would definitely provide the facility you want though.
The best thing to do is avoid that requirement in the first place.
Assuming you're only concerned with application-level thread contention, and assuming you are willing to fuss with locks as suggested by others (which, IMHO, is a really bad idea), then you should use a ReadWriteLock and not simple object synchronization:
import java.java.util.concurrent.locks.*;
// create a fair read/write lock
final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
// the main thread grabs the write lock to exclude other threads
final Lock writeLock = rwLock.writeLock();
// All other threads hold the read lock whenever they do
// *anything* to make sure the writer is exclusive when
// it is running. NOTE: the other threads must also
// occasionally *drop* the lock so the writer has a chance
// to run!
final Lock readLock = rwLock.readLock();
new Thread(new Runnable() {
public void run() {
while(condition) {
writeLock.lock();
try {
*code that must not be interrupted*
} finally {
writeLock.unlock();
}
*some more code*
}
}
}).start();
new SomeOtherThread(readLock).start();
new YetAntherThread(readLock).start();
Actually, you can do this if you control the thread instance you are running on. Obviously, there are a ton of caveats on this (like hanging io operations), but essentially you can subclass Thread and override the interrupt() method. you can then put some sort of boolean in place such that when you flip a flag, interrupt() calls on your thread are either ignored or better yet stored for later.
You really need to leave more info.
You cannot stop other system processes from executing unless you run on a real-time OS. Is that what you mean?
You cannot stop garbage collection, etc unless you run a real-time java. Is that what you wanted?
The only thing left is: If you simply want all YOUR other java threads to not interrupt each other because they all tend to access some resource willy-nilly without control, you are doing it wrong. Design it correctly so that objects/data that NEED to be accessed in a synchronized manner are synchronized then don't worry about other threads interrupting you because your synchronized objects are safe.
Did I miss any possible cases?
Using the synchronized approach ( in the various forms posted here ) doesn't help at all.
That approach only helps to make sure that one thread executes the critical section at a time, but this is not what you want. You need to to prevent the thread from being interrupted.
The read/write lock seems to help, but makes no difference since no other thread is attempting to use the write lock.
It only makes the application a little slower because the JVM has to perform extra validations to execute the synchronized section ( used only by one thread , thus a waste of CPU )
Actually in the way you have it, the thread is not "really" being interrupted. But it seems like it does, because it has to yield CPU time to other threads. The way threads works is; the CPU gives to each thread a chance to run for a little while for very shorts periods of time. Even one when a single thread running, that thread is yielding CPU time with other threads of other applications ( Assuming a single processor machine to keep the discussion simple ).
That's probably the reason it seems to you like the thread is being paused/interrupted from time to time, because the system is letting each thread in the app run for a little while.
So, what can you do?
To increase the perception of no interruptions, one thing you can do is assign a higher priority to your thread and decrease it for the rest.
If all the threads have the same priority one possible schedule of threads 1,2,3 could be like this:
evenly distributed
1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3
While setting max for 1, and min for 2,3 it could be like this:
More cpu to thread 1
1,1,1,2,1,1,3,1,1,1,2,1,1,1,3,1,2,1,1,1
For a thread to be interrupted by another thread, it has to be in an interruptable state, achieved by calling, Object.wait, Thread.join, or Thread.sleep
Below some amusing code to experiment.
Code 1: Test how to change the priority of the threads. See the patterns on the ouput.
public class Test {
public static void main( String [] args ) throws InterruptedException {
Thread one = new Thread(){
public void run(){
while ( true ) {
System.out.println("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
}
}
};
Thread two = new Thread(){
public void run(){
while ( true ) {
System.out.println(".............................................");
}
}
};
Thread three = new Thread(){
public void run(){
while ( true ) {
System.out.println("------------------------------------------");
}
}
};
// Try uncommenting this one by one and see the difference.
//one.setPriority( Thread.MAX_PRIORITY );
//two.setPriority( Thread.MIN_PRIORITY );
//three.setPriority( Thread.MIN_PRIORITY );
one.start();
two.start();
three.start();
// The code below makes no difference
// because "one" is not interruptable
Thread.sleep( 10000 ); // This is the "main" thread, letting the others thread run for aprox 10 secs.
one.interrupt(); // Nice try though.
}
}
Code 2. Sample of how can be a thread actually be interrupted ( while sleeping in this case )
public class X{
public static void main( String [] args ) throws InterruptedException {
Thread a = new Thread(){
public void run(){
int i = 1 ;
while ( true ){
if ( i++ % 100 == 0 ) try {
System.out.println("Sleeping...");
Thread.sleep(500);
} catch ( InterruptedException ie ) {
System.out.println( "I was interrpted from my sleep. We all shall die!! " );
System.exit(0);
}
System.out.print("E,");
}
}
};
a.start();
Thread.sleep( 3000 ); // Main thread letting run "a" for 3 secs.
a.interrupt(); // It will succeed only if the thread is in an interruptable state
}
}
Before a thread is interrupted, security manager's checkAccess() method is called.
Implement your own security manager, call System.setSecurityManager to install it and make sure it doesn't let any other thread interrupt you while it is in critical section.
Error processing is an example of a use case where it is very useful to stop threads from being interrupted. Say you have a large multi-threaded server and some external condition arises that causes errors to be detected on multiple worker threads simultaneously. Each worker thread generates a notification that an error occurred. Let's say further the desired response is to bring the server to a safe state that will allow it to restart after the error condition is cleared.
One way to implement this behavior is to have a state machine for the server that processes state changes in total order. Once an error notification arrives, you put it into the state machine and let the state machine process it in toto without interruption. This is where you want to avoid interruptions--you want the first notification to cause the error handler to run. Further notifications should not interrupt or restart it. This sounds easy but really isn't--suppose the state machine was putting the server online. You would want to interrupt that to let error processing run instead. So some things are interruptible but others are not.
If you interrupt the error processing thread it may blow the error handler out of the water during synchronized method processing, leaving objects in a potentially dirty state. This is the crux of the problem--thread interrupts go around the normal synchronization mechanism in Java.
This situation is rare in normal applications. However, when it does arise the result can be byzantine failures that are very difficult to anticipate let alone cure. The answer is to protect such critical sections from interrupts.
Java does not as far as I can tell give you a mechanism to stop a thread from being interrupted. Even if it did, you probably would not want to use it because the interrupt could easily occur in low-level libraries (e.g., TCP/IP socket processing) where the effect of turning off interrupts can be very unpredictable.
Instead, it seems as if the best way to handle this is to design your application in such a way that such interrupts do not occur. I am the author of a small state machine package called Tungsten FSM (https://code.google.com/p/tungsten-fsm). FSM implements a simple finite-state machine that ensures events are processed in total order. I'm currently working on a bug fix that addresses exactly the problem described here. FSM will offer one way to address this problem but there are many others. I suspect most of them involve some sort of state machine and/or event queue.
If you take the approach of preventing interruptions it of course creates another problem if non-interruptible threads become blocked for some reason. At that point you are simply stuck and have to restart the process. It does not seem all that different from a deadlock between Java threads, which is in fact one way non-interruptible threads can become blocked. There's really no free lunch on these types of issues in Java.
I have spent a lot of time looking at problems like this--they are very difficult to diagnose let alone solve. Java does not really handle this kind of concurrency problem very well at all. It would be great to hear about better approaches.
Just start your own sub-thread, and make sure that the interrupt calls never filter through to it.
new Thread(new Runnable() {
public void run() {
Thread t = new Thread() {
public void run() {
*code that must not be interrupted*
}
}
t.start(); //Nothing else holds a reference to t, so nothing call call interrupt() on it, except for your own code inside t, or malicious code that gets a list of every live thread and interrupts it.
while( t.isAlive() ) {
try {
t.join();
} catch( InterruptedException e ) {
//Nope, I'm busy.
}
}
*some more code*
}
}
}).start();
SomeOtherThread.start();
YetAntherThread.start();
I think you need to lock on an interrupt flag. What about something like this (not tested):
new Thread() {
boolean[] allowInterrupts = { true };
#Override
public void run() {
while(condition) {
allowInterrupts[0] = false;
*code that must not be interrupted*
allowInterrupts[0] = true;
*some more code*
}
}
#Override
public void interrupt() {
synchronized (allowInterrupts) {
if (allowInterrupts[0]) {
super.interrupt();
}
}
}
}.start();
SomeOtherThread.start();
YetAntherThread.start();
Best halfway solution would be to synchronize all threads on some common object so that no other threads are runnable while you're in the critical section.
Other than that I do not think it's possible. And I'm quite curious as to what kind of problem that requires this type of solution ?
A usual program does not randomly interrupt threads. So if you start a new Thread and you are not passing the reference to this Thread around, you can be quite sure that nothing will interrupt that Thread.
Keep the reference to the Thread private is sufficient in most scenarios. Everything else would be hacky.
Typically work queues like ExecutorService will interrupt their Thread's when asked to do so. In these cases you want to deal with interrupts.