my task is to create thread in this order: if A start->start B and C, if B start->start D.
And destroy them in reverse order If D then B. If B and C then A. I hope you get it. I manage to do it but I guess there is better way to do it. Do you have any suggestions?
After your comments i have changed my code and it is much more simply. But now it looks "stupid". I would like to change hardcore of if statements and implementation, any advice? tnx for advice I'm learning with you.
This is my new code:
import java.util.*;
class RobotController implements Runnable{
String name;
public void run() {
Thread t = Thread.currentThread();
System.out.println(t.getName() + " status = " + t.isAlive());
System.out.println(t.getName() + " status = " + t.getState());
}
public static void main(String args[]) throws InterruptedException{
Thread thread_A = new Thread(new RobotController(), "Thread A");
Thread thread_B = new Thread(new RobotController(), "Thread B");
Thread thread_C = new Thread(new RobotController(), "Thread C");
Thread thread_D = new Thread(new RobotController(), "Thread D");
thread_A.start();
thread_A.join();
System.out.println(thread_A.getState());
thread_B.start();
thread_B.join();
System.out.println(thread_B.getState());
thread_C.start();
thread_C.join();
System.out.println(thread_C.getState());
thread_D.start();
System.out.println(thread_D.getState());
}
}
There are some flaws in your code which will make it not to work accordingly sometimes:
You called thread_A.start() and then checked thread_A.isAlive(). Now what if , thread_A is already completed before thread_A.isAlive() condition is checked?.thread_B and thread_C is never started. Your application fails.
Assume that thread_A is not completed and thread_A.isAlive() condition is passed, then starting of thread_B before thread_C is not always guaranteed by Java thread scheduler. Again your application fails.
Assume that thread_B starts before thread_C and if thread_B completes before thread_B.isAlive() is checked then the if condition fails and thread_D is never started. Again your application fails.
Now a point to ponder:
There is no need to check if the thread is alive after its join() method is called. It is an unnecessary runtime overhead.
EDIT
OK, Here is the modified version of code..I hope it would let you understand the dynamics of thread:
class RobotController implements Runnable
{
private final Object lock = new Object();
private void notifyThread()
{
synchronized(lock)
{
lock.notify();
}
}
public void run()
{
synchronized(lock)
{
try
{
System.out.println(Thread.currentThread().getName() + " started");
lock.wait();
System.out.println(Thread.currentThread().getName()+ " stopped");
}
catch (InterruptedException ex)
{
ex.printStackTrace();
}
}
}
public static void main(String args[]) throws InterruptedException
{
RobotController rca = new RobotController();
RobotController rcb = new RobotController();
RobotController rcc = new RobotController();
RobotController rcd = new RobotController();
Thread thread_A = new Thread(rca,"Thread A");
Thread thread_B = new Thread(rcb,"Thread B");
Thread thread_C = new Thread(rcc,"Thread C");
Thread thread_D = new Thread(rcd,"Thread D");
thread_A.start();
while (thread_A.getState() != Thread.State.WAITING)
{
Thread.sleep(100);
}
thread_B.start();
thread_C.start();
while (thread_B.getState() != Thread.State.WAITING && thread_C.getState() != Thread.State.WAITING)
{
Thread.sleep(100);
}
thread_D.start();
while (thread_D.getState() != Thread.State.WAITING)
{
Thread.sleep(100);
}
rcd.notifyThread();
thread_D.join();
rcc.notifyThread();
thread_C.join();
rcb.notifyThread();
thread_B.join();
rca.notifyThread();
}
}
And here is the output:
Thread A started
Thread B started
Thread C started
Thread D started
Thread D stopped
Thread C stopped
Thread B stopped
Thread A stopped
In multi threading, there is no need of synchronization unless the common data is shared by multiple threads.
In your case, you want to start and stop the threads in a particular order. For this, there is join method in Thread class. This link shows good example of join method.
In my opinion, it is quite strange to use synchronized (lock) in your run method to lock your object. The reason is that in each Thread object has the different lock attribute, which is belong to each object. It means you are trying to lock the different objects. Actually, it doesn't make sense.
Basically, the object that you should apply the synchronized are any shared objects. For example, you need to count something and then you create a class object to share it in your class. In this case, it should be locked while being read or written.
I would like to highlight two points here:
Have a look at thread execution life cycle here. It says that, when start() method is called, thread enters in runnable state and not in running state. When thread enters in running state, that means run() method is getting exexuted. CPU/OS decides the priority of which thread should be transferred from runnable to running thread. E.g. if you call start() method for 4 threads, it is not necessary that they will execute in that particular order. (Running the same program in my pc multiple times gives me different outputs.
In your case, when the condition if(thread_A.isAlive()) is executed, it is possible that the thread A may not be in running state. Hence, the control will not go into if which is not correct.
To correct this behavior, in main, a while loop should implemented which waits until the thread becomes alive and so on.
2 . In your program, you have not assigned names to the threads and you are printing the name in the run() method. In this case, JVM assigns the names to threads in order of their execution e.g. first thread to execute will have name as 'Thread-0' and so on. Hence, we will not be able to identify which thread executed first. Assign the names using setName() method.
Related
I came across the following e example to implement custom suspend and wait from some website.
// Suspending and resuming a thread the modern way.
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();
...................
I am more concerned about the ob1.mysuspend() and ob1.myresume() calls. When my suspend is called then ob1 will be placed into the blocking queue associated with the runnable object it is using. When ob1 calls myresume, then how does it work as ob1 is already in waiting queue for the same object, can the waiting object enters another synchronised method and then signals notify to itself?How does this work?What am I missing?
The thread is written so that while an instance of NewThread is running, another thread can call mysuspend to suspend that running thread. Again, a thread other than the suspended thread calls myresume to resume the suspended thread.
There also appears to be a data race because mysuspend writes to suspendFlag without any synchronization. That means, the thread that needs to be suspended may not see that write immediately. mysuspend must be declared synchronized, or suspendFlag must be volatile.
This code is flat out broken.
Straight up broken: JMM violation
The mysuspend method (which should be named mySuspend, by the way) updates a field that is then read from another thread, and isn't synchronized. This is an error - and a really nasty one because you cannot reliably test that it is an error. The Java Memory Model (JMM) states that any write to a field may be observable or not, at the discretion of the JVM implementation, unless a so-called Happens-Before/Happens-After relationship is established (there are many ways to do it; usually you do so via synchronized, volatile, or some other concurrency tool built on these primitives, such as the latches and queues in the java.util.concurrent package).
You do not establish such a relationship here, meaning, that suspendFlag = true results in a schroedingers cat variable: The other thread that reads this field may read true or false, the JVM gets to decide what you see. Hence: A bug, and, untestable. bad. Any field that is read/written to by multiple threads needs to be written extremely carefully.
Mark that method synchronized, that's a good first step.
Wait and Notify
You've got it flipped around: You must in fact hold the synchronized lock on x when you invoke wait on x (here, x is this).
To call x.wait() (you are calling this.wait(), effectively), you must first be in a synchronized(x) block. Once the wait 'goes through', the code releases the lock (other synchronized(x) blocks can run). To invoke x.notify() you must also hold that lock.
wait does not return until the lock is re-established.
In other words:
public void foo() {
wait();
}
will fail at runtime. Try it. Guaranteed exception. In the mean time, this:
public void foo() {
synchronized (this) {
// code before wait
wait();
// code after wait
}
}
is executed as if it is written like this:
public void foo() {
synchronized (this) {
// code before wait
release_lock(this);
this.wait();
acquire_lock(this);
// code after wait
}
}
Where acquire_lock is guaranteed to actually take a while (because by definition whatever invoked notify() to wake you up is currently holding it! So wait is always a two-hit thing: You need to be both notified AND the lock needs to be reacquired before your code will continue). Except, of course, acquire_lock and release_lock don't exist, and unlike this hypothetical code, wait() is more atomic than that.
I am wondering what happens in the following scenario:
Two threads are created:
Thread t1 = new Thread();
Thread t2 = new Thread();
Assume these just print out a string, the threads then call the .start() method:
t1.start();
t2.start():
My question is why do these threads print in a seemingly random order each time? I know threads execute concurrently but would t1 not always finish before t2 due to the sequential execution of the main process?
Calling start() on a Thread doesn't necessarily result in the thread running immediately after. It is possible for other things to happen in between your calling start() and the first line of your thread's run() method actually being run. And even once your run() is actually running, it's also possible that other things happen before, during, or after your run() method finishes.
In your question, you said: "assume these just print out a string" – here's an implementation of run() which does that:
public void run() {
System.out.println("my name is: " + getName());
}
So it's possible that t1 starts to run first, but before it actually calls System.out.println, t2 is allowed to execute and runs to completion, then t1 is resumed.
If this kind of behavior won't work for your use case, you'll need to add some kind of concurrency protection to coordinate how and when your threads run.
UPDATE:
To illustrate the unpredictable sequence of thread execution, run this code a few times and observe the output:
public class Example {
public static void main(String[] args) {
for (int k = 0; k < 10; k++) {
new TestThread(k).start();
}
}
}
class TestThread extends Thread {
private final int k;
TestThread(int k) {
this.k = k;
}
#Override
public void run() {
System.out.print(k + " ");
}
}
Here is the output from one of my local runs:
7 0 1 5 4 6 3 2 8 9
Thread.start() doesn't guarantee execution. It will just make the Thread state runnable and hand over to the Thread Scheduler. It is the Thread Scheduler which decides which thread to run when.
If you need code to execute in a defined order on multiple threads, you need to add synchronization code between those threads.
Otherwise, the system is free to schedule execution in any order it sees fit.
I'm programming a little Java program where I need to create threads (philosophers in my code), and these philosophers need to change of state between thinking, hungry and eating.
I'm not that far into the project and I have the next problem:
public class NewMain {
static Philosopher [] p;
public static void main(String[] args) {
p = new Philosopher[5];
p[0] = new Philosopher(0);
p[1] = new Philosopher(1);
p[2] = new Philosopher(2);
p[3] = new Philosopher(3);
p[4] = new Philosopher(4);
for (int i = 0; i<5; i++) {
try{
p[i].run();
if(i == 4) {
p.notifyAll();
}
}
catch(IllegalMonitorStateException e) {}
}
}
}
I'm creating 5 philosophers(threads). Each one of those has a wait() instruction in their code:
#Override
public void run() {
int rand;
if (status == 0) {
System.out.println("Philosopher " + id + " is waiting.");
try {
wait();
System.out.println("Awoken");
while(status == 0) {
System.out.println("Philosopher " + id + " is thinking.");
sleep(100);
rand = ThreadLocalRandom.current().nextInt(0,100);
if(rand > 95){
status = 1;
System.out.println("Philosopher " + id + " changed state to hungry.");
}
}
}
catch(InterruptedException e) {
System.out.println("Error!");
}
catch(IllegalMonitorStateException e) {}
}
}
The problem is that when invoking notifyAll(), the processes don't awake and they just die after executing the run() method of each thread.
If anyone is wondering, I'm not using synchronized because I need to run the methods at the same time.
Also, I've tried to put notifyAll() inside the run() method of the threads.
Can anyone tell me what's going on and why are the threads not continuing
with their code?
Problems
notify[All]() and wait() should be used on the same instance. You are notifying on the array Philosopher[] p, but waiting on this which is a Philosopher. It's like I am waiting for you, but you are notifying Sarah that you're going to be late.
You have created the threads but haven't started them properly. Calling run will execute the method in the current thread. Use the method start instead. It begins execution concurrently.
To use x.notify[All]() or x.wait(), you have to be within a synchronised block synchronized(x) { ... }. Ignoring IllegalMonitorStateException won't help you at all.
Answers
... why are the threads not continuing with their code?
They might call wait after the 4th thread notifies them.
... the processes don't awake and they just die ...
They don't die, they still wait until you terminate the program.
I'm not using synchronizedbecause I need to run the methods at the same time
You need to run the methods at the same time correctly, right? Here, synchronisation is required at least for building wait-notify communication.
p is an array of Runnable. when you write
p[i].run();
Then, you are invoking run method (actually you haven't started a thread here instead called run method) using object stored at p[i] location. Now, as per notifyAll
Wakes up all threads that are waiting on this object's monitor. A thread waits on an object's monitor by calling one of the wait methods.
You should have used start() instead run() to start a new thread.
notify() and notifyAll are used when thread(s) are waiting to acquire monitor on current object.
The program creates thread t0 which spawns thread t1 and subsequently threads t2 and t3 are created.After the execution of thread t3and the application never returns to the other threads spawned earlier(t0,t1,t2) and they are left stuck.
Why are the threads t0, t1, and t2 suspended?
public class Cult extends Thread
{
private String[] names = {"t1", "t2", "t3"};
static int count = 0;
public void run()
{
for(int i = 0; i < 100; i++)
{
if(i == 5 && count < 3)
{
Thread t = new Cult(names[count++]);
t.start();
try{
Thread.currentThread().join();
}
catch(InterruptedException e)
{
e.printStackTrace();
}
}
System.out.print(Thread.currentThread().getName() + " ");
}
}
public static void main(String[] a`)
{
new Cult("t0").start();
}
}
The most important point you missed:
Thread.currentThread().join();
Method join in source code uses isAlive method.
public final synchronized void join(long millis)
...
if (millis == 0) {
while (isAlive()) {
wait(0);
}
...
}
It means that Thread.currentThread().join() will return only when Thread.currentThread() is dead.
But in your case it's impossible because of your running code in Thread.currentThread() has itself
this peace of code Thread.currentThread().join(). That's why after Thread 3 completion your program should hang and nothing happens thereafter.
Why are the threads t0, t1, and t2 suspended? The execution of thread t3 completes.
t3 completes because it is not trying to fork a 4th thread and therefore is not trying to join() with it's own thread. The following line will never return so t0, t1, and t2 all stop there and wait forever:
Thread.currentThread().join();
This is asking the current thread to wait for itself to finish which doesn't work. I suspect that you meant to say t.join(); which is waiting for the thread that was just forked to finish.
Here are some other thoughts about your code in no apparent order:
You should consider implements Runnable instead of extends Thread. See here: "implements Runnable" vs. "extends Thread"
You are using the shared static variable count in multiple threads without any protection of locking. The best solution is to use an AtomicInteger instead of a int. You probably don't have a problem here because each thread is modifying count and then forking another thread but if you tried to fork 2 threads, this would be a real problem because of data race conditions.
I'm not sure why you are only spawning another thread if(i == 5 && count < 3). i is only going to be 5 once in that loop. Is that really what you intended?
String[] names = {"t1", "t2", "t3"}; fields are recommended to be declared at the top of classes. Otherwise they get buried in the code and get lost.
In main you start a Cult thread and then the main thread finishes. This is unnecessary and you can just call cult.run(); in main instead and use the main thread.
Cult(String s) { super(s); } there is no point in having a constructor that calls the super constructor with the same arguments. This can be removed.
This is debatable but I tend to put main method at the top of the class and not bury it since it is the "entrance" method. Same thing with constructors. Those should be above the run() method.
catch(Exception e) {} is a really bad pattern. At the very least you should do a e.printStackTrace(); or log it somehow. Catching and just dropping exceptions hides a lot of problems. Also, catching Exception should be changed to catch(InterruptedException e). You want to restrict your catch blocks just the exceptions thrown by the block otherwise this may again hide problems in the future if you copy and paste that block somewhere.
More a good practice but never use constants like 3 that have to match another data item. In this case it would be better to use names.length which is 3. THis means that you don't need to change 2 places in the code if you want to increase the number of threads. You could also have the name be "t" + count and get rid of the names array altogether.
I'm trying to write a Java program that uses threads. I want to be able to run 3 threads when the program starts, and have them waiting on an ArrayList of "work orders".
Initially, theere will be no work orders. So the Threads should just wait.
At some point in the future, work orders will be added to the ArrayList, and the main thread must notify the threads that there is work to do.
I want to be able to do it by extending Thread (instead of implementing Runnable).
I think the main issue I have is that the threads are not correctly synchronized with the workorders ArrayList.
My code looks like this:
public static void main(String[] args) {
AnotherRunnable anotherRunnable = new AnotherRunnable();
ArrayList<ATMRunnable> workOrders = new ArrayList<ATMRunnable>();
T1 t1 = new T1(anotherRunnable, workOrders);
T1 t2 = new T1(anotherRunnable, workOrders);
t1.start();
t2.start();
try{
Thread.sleep(2000);
}
catch(InterruptedException e){}
synchronized (workOrders){
System.out.println(t1.getState() + " - " + t1.getName());
System.out.println(t2.getState() + " - " + t2.getName());
System.out.println("notify");
workOrders.notify();
System.out.println(t1.getState() + " - " + t1.getName());
System.out.println(t2.getState() + " - " + t2.getName());
}
}
The AnotherRunnable class:
public class AnotherRunnable implements Runnable {
public void run()
{
System.out.println("AnotherRunnable");
}
}
And the Tread class:
public class T1 extends Thread {
AnotherRunnable anotherRunnable;
ArrayList<ATMRunnable> workOrders;
ATMThread(AnotherRunnable anotherRunnable, ArrayList<ATMRunnable> workOrders)
{
this.anotherRunnable = anotherRunnable;
this.workOrders = workOrders;
}
public void run()
{
System.out.println("Run Thread");
synchronized (workOrders){
try{
System.out.println("wait Thread");
workOrders.wait();
}
catch (InterruptedException e){}
}
}
}
This is the output of the program:
Run Thread
wait Thread
Run Thread
wait Thread
WAITING - Thread-1
WAITING - Thread-2
notify all
BLOCKED - Thread-1
WAITING - Thread-2
As you can see, the state of the first thread is changed to Blocked, after the call to notify on the workOrders object. But neither the threads nor the runnable object is executed.
Any help will be appreciated.
You should use concurrent collections in java to avoid manual synchronization as far as possible.
I want to be able to run 3 threads when the program starts, and have them waiting on an ArrayList of "work orders". Initially, theere will be no work orders. So the Threads should just wait. At some point in the future, work orders will be added to the ArrayList, and the main thread must notify the threads that there is work to do.
For this kind of synchronization, Blocking queues are your friends like LinkedBlockingQueue which make threads wait when there's no item in the queue or when the queue is full. You do not need any synchronized/wait/notify there.
You can also check if it helps: synchronization is risky
If it is only for learning purpose, you have to make your synchronization proper first logically. It doesn't use any condition for waiting or notifying which is problematic. It'll work if it is proper but its not a preferred way.
I found what I had to do to get this working. Mainly, it was the concept what was missing. I had to loop in the run method of the thread. I was thinking that that method would be called every time notifyall is invoked, which is not true. When wait() is call on the synchronized object, the thread is stopped, and with notify it resumes execution, if that code is not in a loop, it wont be executed.