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.
Related
I was playing with java multithreading code. I created a executor service with fixed thread pool. I am submitting two tasks sequentially. I tried to make the first task really long with the Thread.sleep. I was thinking these two tasks will run parallelly. However, when I run the program, the programs waits for sometime, then prints A B, means the compiler finished the first task at first before going to the second task. Actually, I was expecting, as the second task is a short task, it would be complete before the first task. Any explanation please?
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(10);
Map<String, String> map = new HashMap<>();
ReadWriteLock lock = new ReentrantReadWriteLock();
executor.submit(() -> {
lock.writeLock().lock();
try {
Thread.sleep(10000);
map.put("boo", "mar");
System.out.println("A");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.writeLock().unlock();
}
});
executor.submit(() -> {
lock.writeLock().lock();
try {
Thread.sleep(1);
map.put("foo", "bar");
System.out.println("B");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
lock.writeLock().unlock();
}
});
executor.shutdown();
}
You are "locking" the writeLock BEFORE the first thread sleeps.. so the lock is actually locked for 10 seconds.. then it is unlocked. The second thread was waiting for 10 seconds to acquire the lock.
Sequence of events:
Thread 1: Starts
Thread 2: Starts
Thread 1: Acquire Lock and wait for 10 seconds.
Thread 2: Try to acquire lock (ends up waiting 10 seconds because it is already acquired by Thread 1).
Thread 1: Prints Data.
Thread 1: Unlocks lock.
Thread 2: Acquires lock.
Thread 2: Prints data.
Thread 2: Unlocks lock.
Try something like the below (it acquires the lock only when necessary.. IE: When doing a write operation or modification of the map):
public static void main(String[] args) {
ExecutorService executor = Executors.newFixedThreadPool(10);
Map<String, String> map = new HashMap<>();
ReadWriteLock lock = new ReentrantReadWriteLock();
executor.submit(() -> {
try {
Thread.sleep(10000);
lock.writeLock().lock();
map.put("boo", "mar");
lock.writeLock().unlock();
System.out.println("A");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
executor.submit(() -> {
try {
Thread.sleep(1);
lock.writeLock().lock();
map.put("foo", "bar");
lock.writeLock().unlock();
System.out.println("B");
} catch (InterruptedException e) {
e.printStackTrace();
}
});
executor.shutdown();
}
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.
I have two threads running t1 and t2. When t2 notifies t1, immediately t2 should go to wait state. However, this is not possible as once it notifies t1, it should finish its current process and only after the end of the current thread execution, the t1 execution starts. But i would like to start t1 immediately after t2 notifies so that i can put t2 in wait state for t1 to notify inside the while loop. Is this possible with synchronized block?. I have tried the following code that does not work. I have also commented the coding lines to mention the way i would like to code.
public void passNo(int data)//thread t1
{
this.data1=data;
synchronized(thread2)
{
System.out.println("thread1 running");
data1=data1+100;
try {
Thread.sleep(1000);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("thread1 going to notify thread two");
thread2.notify();
/* try {
thread1.wait();
} catch (Exception e) {
e.printStackTrace();
}*/
}//sync
try {
Thread.sleep(1000);
} catch (Exception e) {}
System.out.println("im done, receiver go");
//}
}
public void ramos(int data)//thread t2
{
synchronized(thread1)
{
try{
System.out.println("I am thread 2 waiting for thread 1");
thread1.wait();//Problem-not notified ever by sender
System.out.println("Notified by sender thread");}
catch(InterruptedException ex){}
System.out.println("I am released");
n=obj.getInteger();
setInteger();
System.out.println("Notified");
}//sync
j++;
//}//while
}
class ClaObj
{
public static void main(String[] args)
{
Sender s=new Sender();
Receiver r=new Receiver();
r.classobj(s);
Thread thread1 = new Thread(s);
Thread thread2 = new Thread(r);
s.sendthrobj(thread1);
r.recvthobj(thread1);
thread1.start();
thread2.start();
}
}
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);
}
}
}