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();
}
}
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 the following Thread example:
class Q
{
int num;
public synchronized void put(int num) {
System.out.println("Put :"+num);
this.num = num;
try {Thread.sleep(100);} catch (Exception e) {}
notify();
try {wait();} catch (Exception e) {}
}
public synchronized void get() {
try {wait();} catch (Exception e) {}
System.out.println("Get :"+num);
notify();
}
}
class Producer implements Runnable
{
Q q;
public Producer(Q q) {
this.q = q;
Thread t = new Thread(this,"Producer");
t.start();
}
public void run() {
int i = 0;
while(true) {
q.put(i++);
try {Thread.sleep(1000);} catch (Exception e) {}
}
}
}
class Consumer implements Runnable
{
Q q;
Thread t;
public Consumer(Q q) {
this.q = q;
t = new Thread(this,"Consumer");
t.start();
}
public void run() {
while(true) {
q.get();
try {Thread.sleep(500);} catch (Exception e) {}
}
}
}
public class InterThread {
public static void main(String[] args) {
Q q = new Q();
new Producer(q);
new Consumer(q);
}
}
I'm trying to run two threads, consumer and producer, in a loop.
sharing the same object q, one thread incrementing q.num and printing the value of it, and the other is consuming q.num by just printing its value.
The result I'm getting in a console is "Put :0" and stops there,
consumer thread not being called, even though I used Thread.sleep(100);
before calling notify() in the producer thread, why !!?
In this case, Producer thread is starting before Consumer. notify() is getting called, following by that wait() getting called. Producer thread goes in waiting state, releases acquired lock.
// producer
notify();
try {
System.out.println(Thread.currentThread().getName() + " Put :"+num);
this.wait(); // lock released
}
catch (Exception e) {
}
Now consumer thread acquires the lock, wait() is executed. Consumer goes in the waiting state.
// consumer
try {
System.out.println(Thread.currentThread().getName() + "Get :"+num);
this.wait(); // Both the threads are waiting
}
catch (Exception e) {
}
Now both the threads are waiting for notify call from the other thread
Note that Sleep() method doesn't release the lock , so there is no point in calling calling Thread.sleep before the producer's notify
difference-between-wait-and-sleep
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.
This is a very short and simple question, but couldn't get the answer from anywhere.
More than one daemon threads can be created?
Yes. You can simply test it with code like
Thread t1 = new Thread(()->{
while(true){
System.out.println("daemon1");
try {
TimeUnit.SECONDS.sleep(1);
} catch (Exception e) {}
}
});
t1.setDaemon(true);
Thread t2 = new Thread(()->{
while(true){
System.out.println("daemon2");
try {
TimeUnit.SECONDS.sleep(2);
} catch (Exception e) {}
}
});
t2.setDaemon(true);
t1.start();
t2.start();
try {
TimeUnit.SECONDS.sleep(5);
} catch (Exception e) {}
System.out.println("main thread stopped");
Output:
daemon1
daemon2
daemon1
daemon2
daemon1
daemon1
daemon1
daemon2
daemon1
main thread stopped
As you see two daemons ware running at the same time. Also since there ware no other non-daemon threads, application stopped.
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);
}
}
}