public static void main(String[] args) throws Exception {
final Exchanger<String> exchanger = new Exchanger<String>();
new Thread(new Runnable() {
#Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + exchanger.exchange("this came from subthread"));
} catch (InterruptedException ex) {
System.out.println("interrupted while waiting for message");
}
}
}).start();
System.out.println(Thread.currentThread().getName() + exchanger.exchange("this came from main thread"));
String s = exchanger.exchange("this came from main thread");
}
Output
mainthis came from subthread
Thread-0this came from main thread
Why does the JVM never quit here?
You have one exchange point in your thread, but 2 exchange points in your main thread. So the second exchange: String s = exchanger.exchange("this came from main thread"); waits forever and prevents the JVM from exiting. If you add a print statement after that line, you will see it does not get executed.
If you add a second exchange in your thread, the program will exit:
public void run() {
try {
System.out.println(Thread.currentThread().getName() + exchanger.exchange("this came from subthread"));
exchanger.exchange("allow JVM to exit here");
} catch (InterruptedException ex) {
System.out.println("interrupted while waiting for message");
}
}
The last line:
String s = exchanger.exchange("this came from main thread");
offers "this came from main thread" for exchange with some other thread, but there's no other thread to make a counter offer.
Related
I think Lock.lock() is not interruptible, while Lock lockInterruptibly() can be interrupted. So I tried:
public static void main(String[] args) throws InterruptedException {
Lock l = new ReentrantLock();
Thread t = new Thread(new Runnable() {
#Override public void run() {
l.lock();
System.out.println("Thread 3 start");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("lock is interrup")
e.printStackTrace();
} finally {
l.unlock();
}
System.out.println("Thread 3 end");
} // end run
});
t.start();
Thread.sleep(1000);
t.interrupt();
t.join();
}
On running it, it prints:
Thread 3 start
lock is interrupted
java.lang.InterruptedException: sleep interrupted
at java.lang.Thread.sleep(Native Method)
at mygroup.UseLock$3.run(UseLock.java:42)
at java.lang.Thread.run(Thread.java:748)
Thread 3 end
Well I expected that Thread 3 is not interruptible because there's l.lock();
So where did I get wrong? What's indeed an non-interruptible thread?
Appreciate your explanations!
As noted in the comments, your test is flawed because the thread is not interrupted when l.lock() is called. In order to test this properly, you should additionally call l.lock() just before t.start(). This will cause the l.lock() call within thread t to block, and the interrupt will arrive while it is blocked, and since l.lock() does not allow interrupts, it should continue to block in spite of the interrupt. After sending the interrupt, your main thread can wait a second or two and then release the lock. In thread t You should then test to make sure that the thread has the interrupt status set immediately upon returning from l.lock(). Here is an example:
Lock l = new ReentrantLock();
// test Lock.lock()
Thread t = new Thread(() -> {
try {
l.lock();
} catch(InterruptedException ex) {
System.out.println("Lock.lock() was interrupted.");
}
if(Thread.interrupted()) {
System.out.println("Thread was interrupted and Lock.lock() was not interrupted.");
} else {
System.out.println("Thread was not interrupted");
}
l.unlock();
});
l.lock();
t.start();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
l.unlock();
t.join();
// now test Lock.lockInterruptibly()
t = new Thread(() -> {
try {
l.lockInterruptibly();
} catch(InterruptedException ex) {
System.out.println("Lock.lockInterruptibly() was interrupted.");
}
if(Thread.interrupted()) {
System.out.println("Thread was interrupted and Lock.lockInterruptibly() was not interrupted.");
} else {
System.out.println("Thread was not interrupted");
}
l.unlock();
});
l.lock();
t.start();
Thread.sleep(1000);
t.interrupt();
Thread.sleep(1000);
l.unlock();
t.join();
This should print:
Thread was interrupted and Lock.lock() was not interrupted.
Lock.lockInterruptibly() was interrupted.
I have a thread with the following run() method.
I wrote this code to conclude a failure after 2 seconds and execute startNewRound() if no interrupt happens in that 2 seconds. If the thread is interrupted while isLateToTimeout = true, it should call startNewRound() and finish the execution so that the thread will be terminated. For any other interrupt, it should start waiting for 2 seconds again.
What I want to know is whether this thread will be terminated(as I have explained above) after startNewRound() call in the catch block.
public void run() {
try {
Thread.sleep(2000);
System.out.println("FAILURE"));
startNewRound();
} catch (InterruptedException e) {
if (isLateToTimeout){
startNewRound();
}
else{
run();
}
}
}
After #BoristheSpider's input, I came up with this solution for the run method.
public void run() {
int i = 0;
while(i<=200){
if (i == 200){
startNewRound();
break;
}
else{
try {
Thread.sleep(10);
} catch (InterruptedException e) {
if (isLateToTimeout){
startNewRound();
break;
}
else{
i = 0;
}
}
}
i++;
}
}
Hope this is the solution to properly terminate the thread after both calls of startNewRound() without causing stackOverflow.
I am using a Java based file conversion tool which converts PDF to DOCX, but sometimes while conversion it stuck, if input file size is more then 1 MB and start utilizing 100% CPU and more memory and keep running. I want to stop this continuous thread.
I know stop() function is deprecated.
Calling thread.interrupt(); is not helping, since thread is keep running.
There is no loop in the code ...so cannot check for interrupted flag in loop
How to Stop a running Thread t.
public class ThreadDemo implements Runnable {
Thread t;
PdfToDocConversion objPdfToDocConversion;
ThreadDemo() throws InterruptedException {
t = new Thread(this);
System.out.println("Executing " + t.getName());
// this will call run() fucntion
t.start();
Thread.sleep(2000);
// interrupt the threads
if (!t.interrupted()) {
System.out.println("Interrupted");
t.interrupt();
}
System.out.println(t.isInterrupted()); // true
System.out.println(t.getName());
System.out.println(t.isAlive()); /// still true
// block until other threads finish
try {
t.join();
} catch (InterruptedException e) {
}
}
public void run() {
objPdfToDocConversion = new PdfToDocConversion();
try {
objPdfToDocConversion.convertDocToPdf();//inside this function thread got stuck
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.out.print(t.getName() + " interrupted:");
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[]) {
try {
new ThreadDemo();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
You can build your own logic in killing the thread by the help of boolean flag.
public class RunningThread implements Thread {
private volatile boolean running = true;
public void run() {
while (running) {
try {
// Add your code here
} catch (InterruptedException e) {
if(!running){
break;
}
}
}
}
public void stopThread() {
running = false;
interrupt();
}
}
Here is the usecase:
RunningThread thread = new RunningThread();
thread.start(); // start the thread
thread.stopThread(); // stops the thread
The approach above is originally used by Google developers in on of there framework a.k.a Volley library.
Thread.interrupt() only sets a flag within the Thread object that the Thread should be interrupted. It does not cause the target Thread to throw an InterruptedException, instead code that can be interrupted must continually check that flag to see if someone has requested it be interrupted. That code then must handle it, usually by throwing an InterruptedException.
Some of the answers say about stopping the loop with volatile boolean isRunning but I do not see any loop in your example. Interrupting the thread does not actually interrupt it "right now". It just says "thread will be interrupted as soon as there will be such an opportunity". In your case I would suggest to close your PDF file and flag it with some boolean - then you can catch the IOException and if the flag is set - it means that you caused this situation and you can finish the thread.
I am using ExecutorService and its blocking the main program for some time but I don't want to block the main program.
Here is the code:
public class Test {
public static void main(String[] args) throws InterruptedException, ExecutionException, TimeoutException {
ExecutorService executor = null;
try {
executor = Executors.newFixedThreadPool(1);
System.out.println("Start 1");
Runnable task = new Runnable() {
public void run() {
System.out.println("Start 2");
try {
Thread.sleep(7000);
System.out.println("Start 5");
} catch (Exception e) {
}
}
};
System.out.println("Start 3");
// executor.execute(task);
Future future = executor.submit(task);
Object result = future.get(9, TimeUnit.SECONDS);
System.out.println("Start 4");
} catch (Exception e) {
} finally {
System.out.println("finally");
executor.shutdownNow();
}
}
}
Output:
Start 1
Start 3
Start 2
Start 5
Start 4
finally
Currently it does not print Start 4 until and unless the thread completes the execution. What I am looking for is some mechanism where we can have a timeout and the thread runs in the background and does not block the main thread?
You are using future.get(9, TimeUnit.SECONDS); This will wait for 9 seconds, for the submitted thread to finish.
If you don't need the main program to wait and also don't require anything to be returned by the thread, then use the executor.execute call.
Here is the updated code...
ExecutorService executor = null;
try {
executor = Executors.newFixedThreadPool(1);
System.out.println("Start 1");
Runnable task = new Runnable() {
public void run() {
System.out.println("Start 2");
try {
Thread.sleep(7000);
System.out.println("Start 5");
}
catch (Exception e) {
}
}
};
System.out.println("Start 3");
executor.execute(task);
System.out.println("Start 4");
}
catch (Exception e) {
}
finally {
System.out.println("finally");
executor.shutdown();
}
}
You are not catching timeout exception in current code before printing Start 4 but you are catching Exception after `Start 4' line. So you are not getting desired output in case of timeout.
Change your code
from
Object result = future.get(9, TimeUnit.SECONDS);
to
try {
Object result = future.get(9, TimeUnit.SECONDS);
} catch (CancellationException ce) {
System.out.println("CancellationException ");
} catch (ExecutionException ee) {
System.out.println("ExecutionException ");
} catch (InterruptedException ie) {
System.out.println("InterruptedException ");
Thread.currentThread().interrupt(); // ignore/reset
}
With above code, you always get Start 4 irrespective of time-out of Future task.
Refer to afterExecute method in ThreadPoolExecutor documentation page for more details.
Regarding blocking of main thread, currently you are using blocking get() call on Future. If you don't want to block your main thread, change ExecutorService to ExecutorCompletionService and use new API as per documentation above page.
In the following example how stop() method is implemented??
What should be done instead of using stop() method?
In my point of view ,When the desired state is suspended, the thread waits using Object.wait. When the thread is resumed, the target thread is notified using Object.notify. but doubtful in case of implentation of stop() in the below example.
Class NewThread implements Runnable {
String name; // name of thread
Thread t;
boolean suspendFlag;
NewThread(String threadname) {
name = threadname;
t = new Thread(this, name);
System.out.println("New thread: " + t);
suspendFlag = false;
t.start(); // Start the thread
}
// This is the entry point for thread.
public void run() {
try {
for(int i = 15; i > 0; i--) {
System.out.println(name + ": " + i);
Thread.sleep(200);
synchronized(this) {
while(suspendFlag) {
wait();
}
}
}
} catch (InterruptedException e) {
System.out.println(name + " interrupted.");
}
System.out.println(name + " exiting.");
}
void mysuspend() {
suspendFlag = true;
}
synchronized void myresume() {
suspendFlag = false;
notify();
}
}
class SuspendResume {
public static void main(String args[]) {
NewThread ob1 = new NewThread("One");
NewThread ob2 = new NewThread("Two");
try {
Thread.sleep(1000);
ob1.mysuspend();
System.out.println("Suspending thread One");
Thread.sleep(1000);
ob1.myresume();
System.out.println("Resuming thread One");
ob2.mysuspend();
System.out.println("Suspending thread Two");
Thread.sleep(1000);
ob2.myresume();
System.out.println("Resuming thread Two");
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
// wait for threads to finish
try {
System.out.println("Waiting for threads to finish.");
ob1.t.join();
ob2.t.join();
} catch (InterruptedException e) {
System.out.println("Main thread Interrupted");
}
System.out.println("Main thread exiting.");
}
}
The thread automatically stop if it returns the run() function.no need to use the stop() function because stop method is deprecated by java and unsafe to use
Calling stop method will kill the thread on which it is called. A thread must only be killed when there is no use of continuing what a thread is doing. When you will call the stop method, the Thread will stop its execution and will die.
It is preferable to allow thread to complete its run method and kill itslef rather than killing it forcefully.
Calling stop() triggers an exception/error to be thrown in the thread at a random point. If you have access to all the code for the thread it can be used safely, however if this the case, you are far better off supporting interrupts.
Instead of Object.wait/notify, you are likely to be better off using high level concurrency library support i.e. use a Lock which would simplify your code.
For more on stop(); Does Thread.stop() really stop a Thread?
It depends on your threads and what they have to do really.
If they are workers that for example listen to a tcp/ip socket, then you're better off having a volatile boolean inside of the class that says wether or not the loop inside your run() method should continue. Then have your class that extends thread implement a pleaseStop() function which puts the boolean to false, which then causes your run method to finish gracefully (you can even clean up your resources then).
On the other hand, if they are workers that have a finite amount of work to be done, then you should just wait for them to be ready, using the join() functionality.
private void jToggleButton1ActionPerformed(java.awt.event.ActionEvent evt) {
// TODO add your handling code here:
if (jToggleButton1.isSelected()) {
jToggleButton1.setBackground(Color.green);
jToggleButton1.setText("ON");
//MainClass main = new MainClass();
new Thread(new Runnable() {
#Override
public void run() {
try {
server = new ServerSocket(4400, 500);
do {
socket = server.accept();
ClientHandler cliendHandler = new ClientHandler(socket);
cliendHandler.start();
} while (true);
} catch (IOException ex) {
}
}
}).start();
} else {
try {
server.close();
jToggleButton1.setText("START SERVER");
jToggleButton1.setBackground(Color.red);
} catch (IOException ex) {
Logger.getLogger(Server_Prog.class.getName()).log(Level.SEVERE, null, ex);
}
}
}