How to stop a thread in java and let the same thread to do another thing?
I start one thread to download contents from th开发者_StackOverflowe internet, at one time, the thread is downloading one file, and then i want it stop and begin to download another file, what should i do? should i count on the concurrency mechanism in java?
You can start your thread using a single-thread executor, then when you kill it (gracefully I hope) and start a new one it will ensure that it's using the same thread.
// Suppose you have a DownloadFile class that implements Runnable
DownloadFile task1 = new DownloadFile();
...
ExecutorService exec = Executors.newSingleThreadExecutor();
Future<Boolean> future = exec.submit( task1, Boolean.TRUE );
...
// Cancel the task
future.cancel();
// Give the executor another task
DownloadFile task2 = new DownloadFile();
...
exec.submit( task2, Boolean.TRUE );
Other useful docs:
- Future
- ExecutorService
Stopping thread using stop()
method is not recommended.
I start one thread to download contents from the internet, at one time, the thread is downloading one file, and then i want it stop and begin to download another file, what should i do?
You need to use the sleep( ) method of Thread
class to pause the same thread for some specified milliseconds
before you can continue the work with the same thread.
Note : Once the thread has been stopped, it can't resume its work. It will result in IllegalThreadStateException.
See :
- Why are Thread.stop() , Thread.suspend() and Thread.resume() Deprecated ?
- How to stop a java thread gracefully ?
To interrupt a thread from a current processing and redirect it to something else is a classic synchronization problem. This is done as follows:
Have a job queue. The jobs in the job queue [or more specifically the objects in the job queue] should have a method [say process()] that the thread will execute. The thread generally does not know the details of the process() method. It only cares that it has to run the process() method.
The thread must wait on the job queue. This is done as follows:
Job j = null;
synchronized(jobQueueInstance)
{
if(jobQueueInstance.isEmpty())
{
jobQueueInstance.wait();
}
j = jobQueueInstance.poll(); //get the job from the head of the queue
}
try
{
j.process();
}
catch(InterruptedException ex)
{
//thread is interrupted, means it needs to abandon this job and fetch a new one from the queue
}
I hope this helps. However I have omitted a few things to oversimplify the problem:
I have omitted the
Job
class declaration, I guess it will either be an interface or an abstract class.I have also omitted the part where some other thread will add a
new Job()
andnotify()
on thejobQueueInstance
.Also omitted the part about the thread that will
interrupt()
the "busy" job-running thread.
NOTE Threads 3 and 4 can be the same thread.
You should place a timeout on your download using the software for downloading. This usually results in an Exception which you can catch, clean up what you are doing and continue on.
Unless the software you are using supports interrupts or time out settings, there is no safe way to force this to happen externally. You can use stop() safely provided your intention is to shutdown at soon as possible. (In which case System.exit() is a better option)
If you have a library which you have no choice but to kill, you need to run it in a separate process and kill the whole process. This will ensure any resources used will be cleaned up by the OS. (Assuming it hasn't left temporary files etc. ;)
精彩评论