I was reading this post and the suggestions given to interrupt one thread from another is
" " " Here are a couple of approaches that should work, if implemented correctly.
You could have both threads regularly check some common flag variable (e.g. call it stopNow), and arrange that both threads set it when they finish. (The flag variable needs to be volatile ... or properly synchronized.)
You could have both threads regularly call the Thread.isInterrupted() method to see if it has been interrupted. Then each thread needs to call Thread.interrupt() on the other one when it finishes." " "
I do not understand how the second approach is possible that is using Thread.isInterrupted().
That is, how can Thread-1 call Thread.interrupt() on Thread-2.
Consider this example, in the main method I start two threads t1 and t2. I want t1 to stop t2 after reaching certain condition. how can I achieve this?
class Thread1 extends Thread {
public void run(){
while (!isDone){
// do something
}
} //now interrupt Thread-2
}
class Thread2 extends Thread {
public void run(){
try {
while(!Thread.isInterupted()){
//do something;
}
catch (InterruptedExecption e){
//do something
}
}
}
public class test {
public static void main(String[] args){
try {
Thread1 t1 = new Thread1();
Thread2 t2 = new Thread2();
t1.start();
t2.start();
} catch (IOException e) {
e.printStackTrace();
}
}
}
The context of this is that you are trying to implement your scheme using thread interrupts.
In order for that to happen, the t1 object needs the reference to the t2 thread object, and then it simply calls t2.interrupt().
There are a variety of ways that t1 could get the reference to t2.
It could be passed as a constructor parameter. (You would need to instantiate Thread2 before Thread1 ...)
It could be set by calling a setter on Thread1.
It could be retrieved from a static variable or array, or a singleton "registry" object of some kind.
It could be found by enumerating all of the threads in the ThreadGroup looking for one that matches t2's name.
public class test {
private static boolean someCondition = true;
public static void main(String[]args){
Thread t2 = new Thread(new someOtherClass("Hello World"));
Thread t1 = new Thread(new someClass(t2));
t2.start();
t1.start();
try {
t1.join();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
static class someClass implements Runnable{
Thread stop;
public someClass(Thread toStop){
stop = toStop;
}
public void run(){
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if(someCondition && !stop.isInterrupted()){
stop.interrupt();
}
}
}
}
static class someOtherClass implements Runnable{
String messageToPrint;
public someOtherClass(String s){
messageToPrint = s;
}
public void run(){
while(true){
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(messageToPrint);
}
}
}
}
You could consider the use of Future interface. It provides a cancel() method.
http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html
Playing with interruption makes your life unnecessarily hard. Besides the fact that your code must know the threads, interruption does not provide any context information about the reason of the interruption.
If you have a condition that is shared by your code possibly executed by different threads, just encapsulate that condition into an object and share that object:
public class Test {
public static void main(String[] args) {
Condition c=new Condition();
new Thread(new Setter(c)).start();
new Thread(new Getter(c, "getter 1")).start();
// you can simply extend it to more than one getter:
new Thread(new Getter(c, "getter 2")).start();
}
}
class Getter implements Runnable {
final Condition condition;
final String name;
Getter(Condition c, String n) { condition=c; name=n; }
public void run() {
while(!condition.isSatisfied()) {
System.out.println(name+" doing something else");
try { Thread.sleep(300); } catch(InterruptedException ex){}
}
System.out.println(name+" exiting");
}
}
class Setter implements Runnable {
final Condition condition;
Setter(Condition c) { condition=c; }
public void run() {
System.out.println("setter: doing my work");
try { Thread.sleep(3000); }
catch(InterruptedException ex){}
System.out.println("setting condition to satisfied");
condition.setSatisfied();
}
}
class Condition {
private volatile boolean satisfied;
public void setSatisfied() {
satisfied=true;
}
public boolean isSatisfied() {
return satisfied;
}
}
The big advantage of this encapsulation is that it is easy to extend. Suppose you want to allow a thread to wait for the condition instead of polling it. Taking the code above it’s easy:
class WaitableCondition extends Condition {
public synchronized boolean await() {
try {
while(!super.isSatisfied()) wait();
return true;
} catch(InterruptedException ex){ return false; }
}
public synchronized void setSatisfied() {
if(!isSatisfied()) {
super.setSatisfied();
notifyAll();
}
}
}
class Waiter implements Runnable {
final WaitableCondition condition;
final String name;
Waiter(WaitableCondition c, String n) { condition=c; name=n; }
public void run() {
System.out.println(name+": waiting for condition");
boolean b=condition.await();
System.out.println(name+": "+(b? "condition satisfied": "interrupted"));
}
}
Without changing the other classes you can now extend your test case:
public class Test {
public static void main(String[] args) {
WaitableCondition c=new WaitableCondition();
new Thread(new Setter(c)).start();
new Thread(new Getter(c, "getter 1")).start();
// you can simply extend it to more than one getter:
new Thread(new Getter(c, "getter 2")).start();
// and you can have waiters
new Thread(new Waiter(c, "waiter 1")).start();
new Thread(new Waiter(c, "waiter 2")).start();
}
}
Related
Below I have constructed an example which synchronizes three threads based on a static variable:
public class CallMethodsInOrder {
public static void main(String[] args) {
// Three instances of Thread, first calls first, second second and third third.
// Ensure that they are all called in order.
Thread first = new Thread(new FooRunner(new Foo(),MethodToCall.FIRST));
Thread second = new Thread(new FooRunner(new Foo(),MethodToCall.SECOND));
Thread third = new Thread(new FooRunner(new Foo(),MethodToCall.THIRD));
third.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
second.start();
first.start();
}
}
class Foo {
static boolean hasFirstRun = false;
static boolean hasSecondRun = false;
static boolean hasThirdRun = false;
public Foo() {
}
public void first() {
System.out.println("First");
hasFirstRun = true;
}
public void second() {
System.out.println("Second");
hasSecondRun = true;
}
public void third() {
System.out.println("Third");
hasThirdRun = true;
}
}
class FooRunner implements Runnable{
private Foo foo;
private MethodToCall method;
public FooRunner(Foo foo, MethodToCall method) {
this.foo = foo;
this.method = method;
}
#Override
public void run() {
if(method == MethodToCall.FIRST) {
foo.first();
}
else if (method == MethodToCall.SECOND){
while(!Foo.hasFirstRun) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
foo.second();
}
else if (method == MethodToCall.THIRD) {
while(!Foo.hasSecondRun) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
foo.third();
}
}
}
enum MethodToCall{
FIRST, SECOND, THIRD;
}
Is this a valid approach? I have read that static variables are not thread safe, however, cannot see a situation in which the above code would not execute the three methods in the desired order (first, second, third).
Many answers I have found have been related to accessing data structures with multiple threads vs ordering of methods as displayed here.
Since each static variable is only being modified by a single thread is it a problem?
As suggested in the comments, using synchronized is likely the way forward here. I feel the above code still works with static variables however is definitely not the best practise.
A related solution including Semaphores is included below:
public class CallMethodsInOrder2 {
public static void main(String[] args) {
// Three instances of Thread, first calls first, second second and third third.
// Ensure that they are all called in order.
// This approach uses Semaphore vs static variables.
Foo2 foo2 = new Foo2();
Thread first = new Thread(new FooRunner2(foo2,MethodToCall.FIRST));
Thread second = new Thread(new FooRunner2(foo2,MethodToCall.SECOND));
Thread third = new Thread(new FooRunner2(foo2,MethodToCall.THIRD));
third.start();
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
second.start();
first.start();
}
}
class Foo2 {
private Semaphore one, two;
public Foo2() {
one = new Semaphore(1);
two = new Semaphore(1);
try {
one.acquire();
two.acquire();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void first() {
System.out.println("First");
one.release();
}
public void second() {
try {
one.acquire();
System.out.println("Second");
one.release();
two.release();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void third() {
try {
two.acquire();
two.release();
System.out.println("Third");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
I think the static variable method 'works' in this case (for some value of 'works'), but is definitely less efficient.
You're sleeping an arbitrary amount of time in each thread ('100'), and then waking up to poll this variable. In the case of a semaphore, the OS takes care of the sleep/wake events to the threads.
In the code and output below, t2 doesn't start until t1 finishes. Shouldn't they work parallel? Is Thread.sleep() affect whole process?
public class Main {
public static void main(String[] args) {
T t1 = new T(), t2 = new T();
t1.run();
t2.run();
}
}
class Test {
private int x;
void foo() {
synchronized (this){
System.out.println("Entered");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Exit");
}
}
}
class T extends Thread {
static Test t = new Test();
public void run() {
System.out.println("Thread started");
t.foo();
}
}
Output:
Thread started
Entered
Exit
Thread started
Entered
Exit
If you want to run these as separate threads, you need to call the Thread.start() method.
Instead, you're calling the run() method directly. The two calls will execute in the same thread as the caller.
As an aside, usually you can just subclass Runnable rather than Thread. Then you can choose to pass your Runnable to the Thread(Runnable) constructor -- or to an ExecutorService.
I am really confused on how synchronization actually work. I have this following code:
public class FunTest {
static FunTest test;
public void method() {
synchronized (test) {
if (Thread.currentThread().getName() == "Random1") {
try {
wait();
} catch (InterruptedException ex) {
ex.printStackTrace();
}
} else {
notify();
}
}
}
public static void main(String[] args) {
test = new FunTest();
final FunTest t0 = new FunTest();
Thread t1 = new Thread(new Runnable() {
public void run() {
t0.method();
}
});
Thread t3 = new Thread(new Runnable() {
public void run() {
t0.method();
}
});
t1.setName("Random1");
t3.setName("Random2");
t1.start();
t3.start();
}
}
The code throws IllegalMonitorStateException when run. I don't understand why this is happening. Is it not possible to acquire lock this way?
If I replace test with this in synchronization block it works fine though. Why is this so?
You're opening a monitor block on test, but your applying wait() and notify() to this.
According to javadoc of wait()
"The current thread must own this object's monitor"
In your case it is not.
changing t0.method(); to test.method() will work. Not sure about your usecase though.
class firstThread extends Helper1
{
Thread thread_1 = new Thread(new Runnable()
{
#Override
public void run() {
try {
for (int i = 1; i <= 20; i++) {
System.out.println("Hello World");
Thread.sleep(500);
if (i == 10) {
Notify();
Wait();
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
class secondThread extends firstThread
{
Thread thread_2 = new Thread(new Runnable()
{
#Override
public void run() {
// TODO Auto-generated method stub
try {
Wait();
for(int i = 1; i<=20; i++)
{
System.out.println("Welcome");
Thread.sleep(100);
}
Notify();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
class Helper1
{
public synchronized void Wait() throws InterruptedException
{
wait();
}
public synchronized void Notify() throws InterruptedException
{
notify();
}
}
public class InheritanceClass {
public static void main(String[] args)
{
Thread f = new Thread(new firstThread().thread_1);
Thread s = new Thread(new secondThread().thread_2);
f.start();
s.start();
}
}
Only the first Thread has an output. Please try my code. I don't know why it happens.
The second thread does not give output, I suppose it's because of Wait() in the secondThread, I don't know what to do.
The problem is with the following code:
class Helper1
{
public synchronized void Wait() throws InterruptedException
{
wait();
}
public synchronized void Notify() throws InterruptedException
{
notify();
}
}
Above, the wait() and notify() calls are equivalent to this.wait() and this.notify(). However, thread1 and thread2 are separate objects so they are not ever going to communicate via this method.
In order for communication to occur, you need a shared lock object. For example:
Object lock = new Object();
firstThread = new firstThread(lock);
secondThread = new secondThread(lock);
and synchronizations like:
void wait(Object lock) {
synchronized(lock) {
lock.wait();
}
}
void notify(Object lock) {
synchronized(lock) {
lock.notify();
}
}
Disclaimer: I would never do this personally, however it does answer the OP's question.
This code is really confusing, which is making it hard to see the underlying problem.
You should never start a class with a lower-case letter since it makes it look like a method/field name (e.g. firstThread).
I'm pretty sure Wait and Notify have no reason to be synchronized.
Why does secondThread inherit from firstThread??? Actually, why do you have those two classes at all? You should just make an anonymous inner class from Helper1 or something.
Anyway, the problem is that when you call Notify() in thread1 it notifies itself, not thread2.
My code gives me a problem.
My code throws IllegalMonitorStateException in setStr which is in Hoge class.
I change Hoge.class into this in setStr. My code correctly finished!
But why did it finish normally?
public class Sample {
static Hoge gh = new Hoge();
static Hoge gh2 = new Hoge();
public static void main(String[] args) {
new Thread() {
private Hoge h2 = gh;
public void run() {
System.out.println("start initialize");
h2.setStr("BazzBazz");
System.out.println("end initialize");
System.out.println("start thread 1");
System.out.println(h2.getStr("thread-1"));
System.out.println("end thread 1");
}
}.start();
new Thread() {
private Hoge h2 = gh2;
public void run() {
System.out.println("start thread 2");
System.out.println(h2.getStr("thread-2"));
System.out.println("end thread 2");
}
}.start();
}
}
class Hoge {
private String fuga = "fugafuga";
public void setStr(String str) {
synchronized(Hoge.class) { //<-HERE ! change "Hoge.class" into "this".
fuga = str;
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
String getStr(String suffix) {
synchronized(Hoge.class) {
return suffix+ fuga;
}
}
}
YoursetStr method should be like this:
public void setStr(String str) {
synchronized(Hoge.class) { //<-HERE ! change "Hoge.class" into "this".
fuga = str;
try {
Hoge.class.wait();//call wait on Hoge.class
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
You should use Hoge.clas.wait() instead of wait(). Why?
Because , as specified in oracle documentation about wait() :
This method should only be called by a thread that is the owner of
this object's monitor.
i.e a thread can't invoke a wait on an object until it owns that object's lock. Otherwise it will throw IllegalMonitorStateException . Here , you are acquiring lock on object of Class of Hoge(i.e Hoge.class) called as class level lock , but was calling wait on the current object of Hoge(this). So it was leading to IllegalMonitorStateException. That's why your code was working fine when you acquiring lock on the current object (this) because wait() in that case was called on the current object (this) itself.
Because this in gh and gh2 are different, this is an instance of Hoge.
So when use Hoge.class, there is noly one synchronized lock, rather than using this which will use two different lock.