I have a ServerState object:
public class ServerState {
public static final LOCK = new ReentrantLock();
public static Map<String, Object> states = new HashMap<>();
}
Thread A:
public class ThreadA extends Thread {
#Override
public void run() {
ServerState.LOCK.lock();
// do some dirty work
ServerState.LOCK.unlock();
}
}
My question is: when thread A has acquired the lock and is doing some dirty work, thread B wants to terminate A immediately but want it release the lock before its terminate, how can I achieve this? I am not looking for use a flag to indicate whether the thread is terminated like this:
public class ThreadA extends Thread {
volatile boolean isFinished = false;
#Override
public void run() {
while (!isFinished) {
ServerState.LOCK.lock();
// do some dirty work
ServerState.LOCK.unlock();
}
}
What I want to achieve is to terminate the thread and release the lock WITHOUT proceeding to the next iteration. Is is possible to do it in Java?
You can use thread interruption mechanism.
If you want to interrupt on LOCK acquiring, you should use LOCK.lockInterruptibly() instead of LOCK.lock():
Thread thread1 = new Thread() {
#Override
void run() {
try {
LOCK.lockInterruptibly();
System.out.println("work");
LOCK.unlock();
} catch (InterruptedException ier) {
this.interrupt()
}
}
};
Then, to stop thread1 just call
thread1.interrupt();
from another thread.
Also I'd suggest to move actual logic from Thread to Runnable:
Thread thread1 = new Thread(
new Runnable() {
#Override
void run() {
try {
LOCK.lockInterruptibly();
System.out.println("work");
LOCK.unlock();
} catch (InterruptedException ier) {
Thread.currentThread().interrupt()
}
}
}
);
Related
look the java wait/notify code. I think, will not print false.
But, when I run the code, print false somtime.
Is it java bug?
public class TestThread {
public static volatile String lock = "111";
public static volatile AtomicBoolean flag = new AtomicBoolean(true);
public static void main(String[] args) throws InterruptedException {
new Thread(new Runnable() {
public void run() {
try {
while (true) {
synchronized (lock) {
flag.compareAndSet(true, false);
lock.wait();
if (!flag.get()) {
System.out.println(flag.get());
}
}
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
new Thread(new Runnable() {
public void run() {
while (true) {
synchronized (lock) {
flag.compareAndSet(false, true);
lock.notify();
}
}
}
}).start();
}
}
console result:
false
false
false
The reason for such a behavior is called spurious wakeup.
Thread may stop waiting and continue it's execution without notify() call. This is a spurious wakeup - a mechanism of operation system thread scheduler.
That's why you always check some condition before calling wait() and set it explicitly before calling notify(). Do not use notify() itself as a guarantee of a job being done.
Example:
Thread 1
synchronized (lock) {
...
while (!condition) {
lock.wait();
}
...
}
Thread 2
synchronized (lock) {
condition = true;
lock.notify();
}
public class DeadLock {
public static void main(String[] args) {
final A a = new A();
final B b = new B();
new Thread(new Runnable(){
#Override
public void run() {
a.aMethod(b);
}
},"Thread-2").start();
new Thread(new Runnable(){
#Override
public void run() {
b.bMethod(a);
}
},"Thread-2").start();
}
}
class A {
public void aMethod(B b) {
System.out.println("A method");
}
}
class B {
public void bMethod(A a) {
System.out.println("B method");
}
}
I understand that Deadlock occurs when two or more threads are blocked waiting for each other. How do I implement the same using the code above? Synchronizing the methods in classes A and B doesn't help.
How do I implement the same using the code above? Synchronizing the methods in classes A and B doesn't help.
The definition of deadlock is that A is locked and needs the lock from B at the same time that B is locked and needs the lock from A.
You aren't going to be able to simulate it with a single thread call because likely the first thread that is started will finish before the second thread starts. This is a race condition where the threads are racing to deadlock or not.
You need to loop in both threads and try the dual lock over and over. Something like the following should work. At some point you will see the output stop.
public void run() {
while (true) {
a.aMethod(b);
}
}
...
public void run() {
while (true) {
b.bMethod(a);
}
}
...
public synchronized void aMethod(B b) {
System.out.println("B method");
b.bMethod(this);
}
...
public synchronized void aMethod(A a) {
System.out.println("A method");
a.aMethod(this);
}
You may also have to remove the System.out.println(...) calls because they also are synchronized which will change the timing of your program and may make it harder to hit a deadlock. Without the output, to detect the deadlock without the output you can attach to the process using jconsole, look at the Threads tab, and click "Detect Deadlock". You can also watch the load of your program. It should be ~200% while 2 threads are spinning and then go to 0 when they are deadlocked.
public static void main(String[] args) {
final Object a = new Object();
final Object b = new Object();
Thread t1 = new Thread() {
#Override
public void run() {
synchronized (a) {
try {
sleep(10000);
} catch (InterruptedException exc) {
//
}
synchronized (b) {
//
}
}
}
};
Thread t2 = new Thread() {
#Override
public void run() {
synchronized (b) {
try {
sleep(10000);
} catch (InterruptedException exc) {
//
}
synchronized (a) {
//
}
}
}
};
t1.start();
t2.start();
}
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.
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();
}
}
My question is how do I make a thread run, then after that another run, then after that another run again, then it repeats itself.
I have a main file
private static ThreadManager threadManager;
public static void main(String[] args)
{
threadManager = new ThreadManager();
}
Then I have a ThreadManager class
public class ThreadManager {
public static final Object lock1 = new Object();
public static ConcThread CT = new ConcThread();
public static SocketThread sThread = new SocketThread();
public static PacketThread packetThread = new PacketThread();
public ThreadManager() {
try {
synchronized (lock1) {
packetThread.packetThread.start();
lock1.wait();
CT.concThread.start();
lock1.wait();
sThread.socketThread.start();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Then I have 3 threads
public class PacketThread implements Runnable {
public Thread packetThread = new Thread(this);
public void run() {
while (true) {
try {
synchronized (ThreadManager.lock1) {
//DoThing1
synchronized (this) {
ThreadManager.lock1.notifyAll();
}
ThreadManager.lock1.wait();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
public class ConcThread implements Runnable {
public Thread concThread = new Thread(this);
public void run() {
while (true) {
synchronized (ThreadManager.lock1) {
try {
//dothing2
synchronized (this) {
ThreadManager.lock1.notifyAll();
}
ThreadManager.lock1.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
public class SocketThread implements Runnable {
public Thread socketThread = new Thread(this);
public void run() {
while (true) {
synchronized (ThreadManager.lock1) {
try {
//dothing3
synchronized (this) {
ThreadManager.lock1.notifyAll();
}
ThreadManager.lock1.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
}
Rather than having a single lock shared between the three threads (which is in-determinant on which thread will pick up after a thread releases the lock), have three separate semaphore/locks, where thread #1 unlocks a semaphore for thread #2 after its task is complete, thread #2 unlocks the semaphore for thread #3, and thread #3 unlocks the semaphore for thread #1.
So it would look something like:
Thread #1 runs (thread #2 and thread #3 are currently blocked)
Thread #1 completes
Thread #1 unlocks semaphore for thread #2
Thread #1 blocks
Thread #2 runs
Thread #2 completes
Thread #2 unlocks semaphore for thread #3
Thread #2 blocks
Thread #3 runs
Thread #3 completes
Thread #3 unlocks semaphore for thread #1
Thread #3 blocks
Hope this helps,
Jason
Have you considered looking at Runnable to identify the chunks of work you have, and an appropriate Executor to control what runs when?