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?
Related
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()
}
}
}
);
Till now I was aware that wait always need notify to work properly.But when tried the below code I am confused a bit about the working of wait and notify. I created three threads t1,t2,t3 and passed the runnable T1,T2 and T3 respectively.According to me when i started the three threads only t1 should print and t2 and t3 should go to waiting state and keeps on waiting as no one is notifying.
But the o/p is unpredictable for me.Can someone please expalin me a bit.Below are my classes.
package com.vikash.Threading;
class T1 implements Runnable {
private State state;
public T1(State state) {
this.state=state;
}
#Override
public void run() {
synchronized (state) {
while(state.getState()!=1) {
try {
state.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (state) {
System.out.println(Thread.currentThread().getName());
state.setState(2);
}
}
}
}
class T2 implements Runnable {
private State state;
public T2(State state) {
this.state=state;
}
#Override
public void run() {
synchronized (state) {
while(state.getState()!=2) {
try {
state.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (state) {
System.out.println(Thread.currentThread().getName());
state.setState(3);
}
}
}
}
class T3 implements Runnable {
private State state;
public T3(State state) {
this.state=state;
}
#Override
public void run() {
synchronized (state) {
while(state.getState()!=3) {
try {
state.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
synchronized (state) {
System.out.println(Thread.currentThread().getName());
state.setState(1);
}
}
}
}
public class Sequence {
public static void main(String[] args) {
State state=new State();
Thread t1=new Thread(new T1(state),"First");
Thread t2=new Thread(new T2(state),"Second");
Thread t3=new Thread(new T3(state),"Third");
t1.start();
t2.start();
t3.start();
}
}
package com.vikash.Threading;
public class State {
private int state=1;
public int getState() {
return state;
}
public void setState(int state) {
this.state = state;
}
}
As per comment I am modifying my question.The o/p sometimes I am getting First second and it does not terminate and sometimes First Second Third and terminate.
Your expectation is incorrect, it is possible for all your threads to print and end as your program is currently written (but this depends on random chance)
It depends on which thread grabs the monitor on state first using the synchronized block that they all have.
Consider this flow:
T1 enters the synchronized (state) block first. T2 and T3 are waiting to enter their synchronized (state) blocks.
T1 doesn't wait as state.getState() == 1, so instead
T1 prints the thread name and assigns 2 to state.state
T1 exits the synchronized block
Either T2 or T3 enter their synchronized (state) block, assume that it is T2 (which one enters first is undefined behaviour in Java, and likely this is random)
So T2 doesn't wait as state.getState() == 2
T2 prints the thread name and assigns 3 to state.state
T2 exits the synchronized block
T3 enters the synchronized block, doesn't wait, and prints the thread name
Program done.
I am trying the Java thread producer and consumer program.
but consumer thread always goes to waiting status .
I unable to debug the issues why consumer thread always goes to waiting status or producer not notify to consumer thread
please help me to fix this . The programs are below.
The communicator class calls the both producer and consumer class
public class Communicator {
Thread t = null;
Thread t1 = null;
public void runThread() {
Producer p = new Producer();
Consumer c = new Consumer(p);
t = new Thread(p);
t1 = new Thread(c);
t.start();
t1.start();
Thread tr = new Thread() {
public void run() {
for (int i = 0; i < 30; i++) {
System.out.println("t::::::::::::: " + t.getState());
System.out.println("t1::::::::::::: " + t1.getState());
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
};
tr.start();
}
public static void main(String[] args) {
Communicator c = new Communicator();
c.runThread();
}
}
This is producer class which append the data in stringbuffer and notify to consumer class
public class Producer extends Thread {
public StringBuffer sb;
public Producer() {
sb = new StringBuffer();
}
public void run() {
synchronized (sb) {
try {
System.out.println("Bala");
sb.append("murugan");
sb.notify();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Below is consumer class code . it wait up to get notifications from producer class.
public class Consumer extends Thread {
public Producer p;
public Consumer(Producer p) {
this.p = p;
}
public void run(){
synchronized (p.sb) {
try {
p.sb.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(p.sb);
}
}
}
There are few problems with your current code in which the Consumer thread always be in waiting state whereas the producer is already terminated.
Also, your StringBuffer object needs to be volatile so that the producer thread writes will be flushed & available to the other thread.
Along with that, I have modified your Producer and Consumer code to make it more realistic (both run in while loop one producing some data and the other receiving the data) as shown below: (I have also added 1 sec sleep to run the things in slower pace so that you can understand the things better):
Consumer class:
public class Producer extends Thread {
public volatile StringBuffer sb;
public Producer() {
sb = new StringBuffer();
sb.append("");
}
public void run() {
synchronized (sb) {
try {
while(true) {
Thread.sleep(1000);
if(sb.toString().equals("")) {
sb.append("murugan");
System.out.println(" producing sb completed *** ");
sb.notify();
} else {
sb.wait();
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Consumer class:
public class Consumer extends Thread {
public Producer p;
public Consumer(Producer p) {
this.p = p;
}
public void run(){
synchronized (p.sb) {
try {
while(true) {
Thread.sleep(1000);
if(p.sb.toString().equals("")) {
p.sb.wait();
} else {
String str = p.sb.toString();
System.out.println(" consuming sb completed **** "+str);
p.sb.replace(0, str.length(), "");
p.sb.notify();
}
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(p.sb);
}
}
}
for your question,"I unable to debug the issues why consumer thread always goes to waiting status or producer not notify to consumer thread".
Actually your consumer is not always in wait status.
You can just put Thread.sleep(1000);before p.sb.wait(); in your Consumer class,then you can see "consumerThread::::::::::::: RUNNABLE" for once.
IMHO,your consumer code runs too fast to get wait status,so you miss the runnable status. You can learn more from other answers.
The Producer is already Terminated, and it already invoked notify() before the Consumer invoke wait().
Since Producer and Consumer extends Thread, update the Communicator class to this:
public class Communicator {
public void runThread() {
final Producer p = new Producer();
final Consumer c = new Consumer(p);
p.start();
c.start();
Thread tr = new Thread() {
public void run() {
for (int i = 0; i < 30; i++) {
System.out.println("t::::::::::::: " + p.getState());
System.out.println("t1::::::::::::: " + c.getState());
try {
Thread.sleep(2000);
} catch (InterruptedException ie) {
ie.printStackTrace();
}
}
}
};
tr.start();
}
public static void main(String[] args) {
Communicator c = new Communicator();
c.runThread();
}
}
If the Producer is not yet Terminated [if (p.getState() != Thread.State.TERMINATED)], that's the only time Consumer will wait:
public class Consumer extends Thread {
public Producer p;
public Consumer(Producer p) {
this.p = p;
}
public void run() {
synchronized (p.sb) {
try {
if (p.getState() != Thread.State.TERMINATED) {
p.sb.wait();
}
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(p.sb);
}
}
}
It´s is not a answer but a suggestion ... You could simplify the whole logic using BlockingQueue to transfer data from Producer(s) to Consumer(s). All waits and notifies would disappear!
Producer(s) send data to be consumed calling BlockingQueue.offer(String)
Consumer(s) wait (blocked) for data calling BlockingQueue.pool();
As per your code, Consumer Thread waits for the Producer to notify about the string appended in the StringBuffer.
If Producer thread gets the chance to acquire the lock on shared StringBuffer object (it enters the synchronized block) then Consumer Thread will go in Blocked state(will not be able to enter the synchronized block) as its also a competitor for the Lock (both compete for acquiring the lock on same shared object).
Producer thread completes its execution, leaves the synchronized block and gets Terminated. Note that the notify code will not have any impact as Consumer thread is not yet waiting on the shared object as it is yet to enter the synchronized block
Consumer thread gets the chance to acquire the lock and enter the synchronized block It waits for some one to give notification on the shared object. But as Producer is already terminated no one gives the notification to Consumer thread and it remains in Waiting state.
Fix : In your case you can simply ensure that Consumer thread is started first and acquires the lock before Producer thread. For this you can have the main thread to sleep for some time after starting the Consumer thread.
t = new Thread(p);
t1 = new Thread(c);
t1.start();
try {
Thread.sleep(1000);
}catch (InterruptedException e) {
e.printStackTrace();
}
t.start();
Key Point : In case you have only 2 threads, one thread should invoke notify and wait. Other thread upon being notified and only the thread in competition for Lock will acquire the lock and do its job. Upon completion of its job it should invoke notify and will wait for the other thread to do job and give notification once done. This way both the threads will get chance to do their jobs one after the other.
I wanted to intentionally do/test java thread deadlock state so I made a following sample code:
public class TestDeadLock extends Thread{
private Integer a=new Integer(9);
public void run(){
if(Thread.currentThread().getName().equals("t1")){
XXXX();
}
else{
ZZZZ();
}
}
public void XXXX(){
System.out.println("inside XXXX");
synchronized(a){
a++;
ZZZZ();
}
System.out.println("xxxxxxxxxxxxxxxxxxx");
//ZZZZ();
}
public synchronized void ZZZZ(){
System.out.println("inside ZZZZ");
synchronized(a){
a--;
XXXX();
}
System.out.println("zzzzzzzzzzzzzzzzzzzzz");
}
public static void main(String[] args) throws InterruptedException {
TestDeadLock tdl=new TestDeadLock();
Thread t1=new Thread(tdl);
Thread t2=new Thread(tdl);
t1.setName("t1");
t2.setName("t2");
t1.start();
t2.start();
Thread.sleep(1000);
System.out.println("=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-="+tdl.a);
}
}
The output came out to be like :
inside XXXX
inside ZZZZ
=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=10
output is NOT exiting.
I wanted to know, was it due to threads reached Dead Lock state? Is it a right example to experience Dead Lock. Suggest or correct me if I am wrong.
No, you are not experiencing a dead lock. You are encountering a StackOverflowError because you are running into an infinite loop.
Note that your method
public synchronized void ZZZZ() {
System.out.println("inside ZZZZ");
XXXX(); // run-time exception
}
is equivalent to
public void ZZZZ() {
synchronized(this) {
System.out.println("inside ZZZZ");
XXXX(); // run-time exception
}
}
You are not causing a dead lock because you are working on two different instances.
Thread 1 locks t1, thread 2 locks t2.
Your ZZZZ() method contains a call to XXXX() method and vice-versa.
Thus, you have created a never-ending chain of calls that goes: ZZZZ() -> XXXX() -> ZZZZ() -> XXXX() -> etc.
Eventually, your stack will grow too large from all the nested method calls that get pushed onto the stack. Hence, the exceptions that you are getting.
Try this example:
public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.start();
}
private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 2...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 1...");
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
This accurately shows threads reaching deadlock.
Here is the solution:
public class TestThread {
public static Object Lock1 = new Object();
public static Object Lock2 = new Object();
public static void main(String args[]) {
ThreadDemo1 T1 = new ThreadDemo1();
ThreadDemo2 T2 = new ThreadDemo2();
T1.start();
T2.start();
}
private static class ThreadDemo1 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 1: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 1: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 1: Holding lock 1 & 2...");
}
}
}
}
private static class ThreadDemo2 extends Thread {
public void run() {
synchronized (Lock1) {
System.out.println("Thread 2: Holding lock 1...");
try { Thread.sleep(10); }
catch (InterruptedException e) {}
System.out.println("Thread 2: Waiting for lock 2...");
synchronized (Lock2) {
System.out.println("Thread 2: Holding lock 1 & 2...");
}
}
}
}
}
Source: http://www.tutorialspoint.com/java/java_thread_deadlock.htm
Example given by Jase Pellerin is a good example of dead lock but it has one mistake (Sorry Jase Pellerin , i am sure you did it unintetionally) . Here, both methods are trying to get hold of Lock1 first and then Lock2. I think it should be other way around.
Thread1{
synchronized (Lock1) {
synchronized (Lock2) {}
}
}
Thread2{
synchronized (Lock2) {
synchronized (Lock1) {}
}
}
public class TwoThreads {
private static Object resource = new Object();
private static void delay(long n) {
try
{
Thread.sleep(n);
}
catch (Exception e)
{
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.print("StartMain ");
new Thread1().start();
delay(1000); //dealay 1
Thread t2 = new Thread2();
t2.start();
delay(1000); // delay 2
t2.interrupt(); //step 7
delay(1000); //delay 3
System.out.print("EndMain ");
}
static class Thread1 extends Thread {
public void run() {
synchronized (resource) {
System.out.print("Startl ");
delay(6000);
System.out.print("End1 ");
}
}
}
static class Thread2 extends Thread {
public void run() {
synchronized (resource) {
System.out.print("Start2 ");
delay(2000);
System.out.print("End2 ");
}
}
}
}
At step 7 (as I have marked), main thread calls interrupt() on thread t2, but as it was waiting to acquire the lock on a resource, it doesn't throw any exception. After that, main thread prints "End Main" after waiting 1000 ns. In other words, main thread has completed its task, so what triggers t2.interrupt() again because it throws exception after that?
Here is how your program runs, with timestamps:
0000 StartMain
0000 Startl
3000 EndMain
6000 End1
6000 Start2
6000 End2
Why (timestamps in brackets)?
[0000] main launches Thread1, which acquires a lock and sleeps for 6 seconds
[1000] main launches Thread2, which can't acquire the lock held by Thread1 for 6 seconds
[2000] main interrupts Thread2 setting its interrupted flag to true, but Thread2 is waiting for a lock and does not do anything about it
[3000] main ends
[6000] Thread1 finishes sleeping and releases the lock
[6000] Thread2 can acquire it and starts to sleep (its interrupted flag is still on)
[6000] sleep detects that Thread2 has been interrupted and throws an exception immediately
[6000] Thread2 finishes, allowing the JVM to exit
You need a ReentrantLock.
public class TwoThreads {
private static Lock lock = new ReentrantLock();
private static void delay(long n) {
try {
Thread.sleep(n);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
System.out.print("StartMain ");
new Thread1().start();
delay(1000); //dealay 1
Thread t2 = new Thread2();
t2.start();
delay(1000); // delay 2
t2.interrupt(); //step 7
delay(1000); //delay 3
System.out.print("EndMain ");
}
static class Thread1 extends Thread {
public void run() {
try {
lock.lockInterruptibly();
try {
System.out.print("Startl ");
delay(6000);
System.out.print("End1 ");
} finally {
lock.unlock();
}
} catch (InterruptedException ex) {
// Interrupted.
}
}
}
static class Thread2 extends Thread {
public void run() {
try {
lock.lockInterruptibly();
try {
System.out.print("Start2 ");
delay(2000);
System.out.print("End2 ");
} finally {
lock.unlock();
}
} catch (InterruptedException ex) {
// Interrupted.
}
}
}
}
Prints:
StartMain Startl EndMain End1
It´s because the JVM kills your threads when the main thread is shutting down.