I have created sample program of java Thread in which i am using stop() method to stop the thread using below program
public class App extends Thread
{
Thread th;
App(String threadName)
{
th = new Thread(threadName);
}
public synchronized void run() // Remove synchronized
{
for (int i = 0; i < 5; i++) {
System.out.println(th.getName()+" "+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
public static void main( String[] args )
{
App thread_1 = new App("Thread-1");
thread_1.start();
thread_1.setPriority(MAX_PRIORITY); //Comment this
thread_1.stop();
App thread_2 = new App("Thread-2");
thread_2.start();
}
}
The output of the above program is :
Thread-1 0
Thread-1 1
Thread-1 2
Thread-1 3
Thread-1 4
Thread-2 0
Thread-2 1
Thread-2 2
Thread-2 3
Thread-2 4
i.e. thread_1 is not stopped. When i am removing synchronized or priority in the code thread is stopped immediately and output will be
Thread-2 0
Thread-2 1
Thread-2 2
Thread-2 3
Thread-2 4
I am not able to understand why it is working like this.
Most of the public methods of the Thread class are synchronized on the Thread instance itself. http://hg.openjdk.java.net/jdk6/jdk6/jdk/file/5672a2be515a/src/share/classes/java/lang/Thread.java
Your run() method is synchronized on the Thread instance. The stop() method calls stop(Throwable), which is also synchronized on the Thread instance, its signature is:
#Deprecated
public final synchronized void stop(Throwable obj) {
The synchronization prevents the main thread from entering thread_1.stop() while the thread itself is still running in your synchronized run() method.
This is an example of why it's wise to always use private objects for synchronization. E.g., do this...
class Foobar {
private final Object lock = new Object();
public void do_something() {
synchronized(lock) {
...
}
}
}
Instead of doing this...
class Foobar {
public synchronized void do_something() {
...
}
}
The second version is more verbose (Welcome to Java!), but it prevents the user of your Foobar class from using it as a synchronization object in a way that interferes with its own use of itself as a synchronization object.
Thread.stop() is deprecated. consider using this instead:
public class App extends Thread
{
Thread th;
volatile boolean bStopThread;
App(String threadName)
{
th = new Thread(threadName);
bStopThread = false;
}
public void stopThread(){
bStopThread = true;
}
public synchronized void run() // Remove synchronized
{
for (int i = 0; i < 5; i++) {
if(bStopThread) return;
System.out.println(th.getName()+" "+i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
}
public static void main( String[] args ) throws InterruptedException
{
App thread_1 = new App("Thread-1");
thread_1.start();
thread_1.setPriority(MAX_PRIORITY); //Comment this
thread_1.stopThread();
App thread_2 = new App("Thread-2");
thread_2.start();
}
}
It should works as you want, although I haven't tested.
You have 3 threads in your application: main thread, running the code of the main method, thread_1 and thread_2. Your main thread starts thread_1 at some point in time X, then calls thread_1.stop() in some point in time Y, Y>X.
Now, what can happen between points X and Y, is that CPU scheduler can decide: "I will now let thread_1 run". Thread_1 will get CPU, will run and will print his text. OR, CPU scheduler can decide: "main thread is now running... let it run". And thread_1 will not get CPU until stop is called and will print nothing.
So you have uncertainty outside of your control about CPU scheduling. You can only assume that raising the priority of the thread hints scheduler to pick the first of the aforementioned choices.
But. stop is deprecated, so never use that. And don't try to guess the order of the execution of the multiple threads.
Put a try catch in your main method. Print stack trace and message of caught exception. Same in run method. Then java will tell you issue.
MHC's method is better but like I said - sometimes (rarely) when you have no control over the thread, can only call stop. But in this case you do have control over it so MHC method will work nicely.
But I do not see what is the issue with your code - it runs fine in my laptop, maybe you did not clean and re compile? Chane some message so you know latest code is running
I used :
package academic.threads;
public class StopThHighPri extends Thread {
Thread th;
volatile boolean bStopThread;
StopThHighPri(String threadName) {
th = new Thread(threadName);
bStopThread = false;
}
public void stopThread(Thread t) {
//bStopThread = true;
try {
t.stop();
} catch (Throwable e) {
System.err.println(" Stop th " + e + " " + e.getMessage());
}
}
public synchronized void run() // Remove synchronized
{
try {
for (int i = 0; i < 5; i++) {
if (bStopThread)
return;
System.out.println(th.getName() + " " + i);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
}
}
} catch (Exception e) {
e.printStackTrace();
System.out.println("run err " + e);
}
}
public static void main(String[] args) {
try {
System.err.println("Code version 002");
StopThHighPri thread_1 = new StopThHighPri("Thread-1");
thread_1.start();
thread_1.setPriority(MAX_PRIORITY); // Comment this
thread_1.stopThread(thread_1);
StopThHighPri thread_2 = new StopThHighPri("Thread-2");
thread_2.start();
} catch (Exception e) {
e.printStackTrace();
System.out.println("MNain err " + e);
}
}
}
Put something like System.err.println("Code version 002");
and change the 002 , 003. so you know latest code is working every time you edit the class. Again for learning this is okay but do not need to use stop here
Related
I'm learning Java threads and want my code to output threads 0-9 in sequential order. I used the synchronized keyword but I don't get the results I expect.
What should I do to correct my code?
public class MyThread extends Thread {
private static final int threadMax = 10;
private static int runCount = 0;
public void printThread() {
synchronized (this) {
while (runCount++ < 100) {
System.out.println(runCount + ": " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void run() {
printThread();
}
public static void main(String[] args) {
for (int i = 0; i < threadMax; i++) {
new MyThread().start();
}
}
}
It is not working as every time you are creating new MyThread object and you are synchronized over that new object. So, every Thread you created will get a lock on the diffrent object. So, you should pass a common object to take the lock like below.
class MyThread extends Thread {
private static int runCount = 0;
Object lock;
public MyThread(Object lock) {
this.lock = lock;
}
public void printThread() {
synchronized (lock) {
// your code here
}
}
//.........
}
And then call it like :
Object lock = new Object();
for (int i = 0; i < threadMax; i++) {
new MyThread(lock).start();
}
However, the above program will not ensure you that it will run in sequence. There are several ways to do that. You can use wait() and notify() to achieve your goal. Refer the below example :
public void printThread() {
while (runCount < 90) {
synchronized (lock) {
while (runCount % 10 != remainder) {
try {
lock.wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
System.out.println(runCount + ": " + Thread.currentThread().getName());
runCount++;
lock.notifyAll();
}
}
}
And call the thread like :
Object lock = new Object();
for (int i = 0; i < 10; i++) {
new MyThread(lock, i).start();
}
You are synchronizing the context of the thread, which is different for each one. You should put into the synchronized key any common object for all diferent threads. This won't make them run in any certain secuence, just to wait each other to end.
If you want to test the synchronized keyword for any purpose, you could pass the constructor a common variable and use it in every thread:
public class MyThread extends Thread {
private static final int threadMax = 10;
private static int runCount = 0;
private Object test; //Object pointing main method
public MyThread(Object test){
this.test = test; //This won't copy values as it is an object and not a number, string...
}
public void printThread() {
synchronized (test) { //Same object for all threads
while (runCount++ < 100) {
System.out.println(runCount + ": " + Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public void run() {
printThread();
}
public static void main(String[] args) {
Object test; //common object
for (int i = 0; i < threadMax; i++) {
new MyThread(test).start();
}
}
}
If you want also to make them start in order, you should "synchronize" the loop making wait and notify calls.
Anyway, the point about multithreading is to have several threads running at the "same" time and not in sequence, as that would be the same as a linear execution.
You have several tasks that you want to delegate to threads but have them executed sequentially.
As others have pointed out, wait & notify can help you achieve that : wait until Nth have finished then notify the next. However, if you wait/notify inside your printThread method, as all your threads are waiting simultaneously on the same lock, there is no guaranties that N+1th thread will be next. So you may have
1: thread-1
...
10: thread-1
11: thread-5
...
20: thread-5
21: thread-2
...
If that's ok for you, you're done. However, in a situation where you specifically want your threads to be ordered, what you need is a waiting queue (FIFO : First In First Out).
To achieve that, you can use the awesome ExecutorService. Be aware however that they hide the Threads from you and picking that solution should not be at the cost of understanding the basics of them beforehand.
An ExecutorService is a very convenient class that can receive tasks (in the form of a Runnable, see below) and will execute them in separate Threads.
Here, I'm using a SingleThreadExecutor which execute the submitted tasks sequentially. So all you have to do is call it's execute method with your tasks as arguments, and the ExecutorService will run them in the right order, one after the other.
Here's what you can do with a few notes :
public class ThreadRunner {
// Note : Constants are usually all uppercase in Java
private static final int MAX_THREADS = 10;
private final int threadName;
public ThreadRunner(int threadName) {
this.threadName = threadName;
}
public void printThread() {
// Note: For loops are better than while when you already know the number of iterations
for (int runCount = 0; runCount < 10; runCount++) {
System.out.println(runCount + "th run from thread " + threadName);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public static void main(String[] args) {
ExecutorService executorService = Executors.newSingleThreadExecutor();
for (int i = 0; i < MAX_THREADS; i++) {
int threadName = i + 1;
// Submit a task to the executor
executorService.execute(() -> new ThreadRunner(threadName).printThread());
}
// Nicely ask for the executor to shutdown.
// Then wait for already submitted tasks to terminate.
executorService.shutdown();
try {
executorService.awaitTermination(120, TimeUnit.SECONDS);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I changed a few details, here are the reasons :
Thread creation : don't inherit from Thread
I would advise you not to inherit from Thread, but create a local instance of it, as all you need is to use a Thread ; you don't want to be a Thread :
public static void main(String[] args) {
// Using Java 1.8+ lambda
Thread lambdaThread = new Thread(() -> System.out.println("Hello from a lambda in a Thread"));
lambdaThread.start();
// Using an anonymous class for java <1.8
Thread anonClassThread = new Thread(new Runnable() {
#Override
public void run() {
System.out.println("Hello from an anonymous class in a Thread");
}
});
anonClassThread.start();
}
You're creating a new Thread passing a Runnable as constructor argument, using either lambda or anonymous class, depending of your Java version.
A Runnable is simply a portion of code that will be executed (by a Thread, in this case).
Same apply to ExecutorService, it's execute methode takes a Runnable which I've created through lambdas.
Sharing static counter between threads
Your line private static int runCount = 0; is a static field, which means it is shared by all instances of the class MyThread. When you increase it in a thread, all threads will read (and write) to the same variable.
If your threads were running sequentially, the first would do it's 100 iterations, then when the second thread starts, runCount is already at 100 and you're not entering your while loop. If that wasn't intended, it may be confusing when you'll test your code.
Based on your expected output in a comment, I believe you want your threads to do 10 iterations each, not share a pool of 100 iterations and manage somehow to have each of them only perform 10.
Having the name of the thread belong to each ThreadRunner
Small detail here : previously, you were creating 10 threads. Here, the ExecutorService only creates one that he reuse for each task you submit. So Thread.currentThread().getName() would always be thread-1.
You wouldn't be able to see which task is running without this field.
If each task is started after the previous, you don't need 10 Threads, but a single Thread performing the 10 tasks sequentially.
I've been as complete as possible, but some points might be a little bit tricky, so don't hesitate to ask for clarifications!
I have a simple test program (garage simulation) with several threads (Vehicle, MysteryVehicle, Observer objects) instantiated and started. Only the Observer object is a daemon thread running an infinite loop.
After all non-daemon threads terminate, Observer thread never does and the loop is executed infinitely (so this isn't some buffered output after the daemon thread really terminates - it does go on forever).
All of the non-daemon threads print something to the console just before exiting their run() methods, and it clearly shows all of them really terminated. I also didn't call join() on the daemon thread. When printing out all currently running threads, observer is listed as well, so my guess is that this daemon thread isn't terminating properly.
The complete code can be found on this commit.
Below you can see all threads created, started and where exactly is join() called.
Main.java
package garage;
import java.util.Set;
import garage.model.*;
import javafx.application.Application;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
Platform platform = new Platform();
Vehicle.platform = platform;
platform.print();
Vehicle[] vehicles = new Vehicle[30];
for (int i = 0; i < 30; i++) {
vehicles[i] = new Vehicle();
}
for (int i = 0; i < 30; i++) {
vehicles[i].start();
}
Observer observer = new Observer();
observer.platform = platform;
observer.start();
MysteryVehicle mysteryVehicle = new MysteryVehicle();
mysteryVehicle.start();
try {
mysteryVehicle.join();
} catch (Exception exception) {
exception.printStackTrace();
}
try {
for (int i = 0; i < 30; i++)
vehicles[i].join();
} catch (Exception exception) {
exception.printStackTrace();
}
System.out.println("before");
platform.print();
System.out.println("after");
synchronized (Platform.lock) {
System.out.println("END");
System.out.println(platform.flag); // checks whether wait() was called anytime
}
Set<Thread> threads = Thread.getAllStackTraces().keySet();
for (Thread t : threads) {
System.out.println(t.getName());
}
}
public static void main(String[] args) {
launch(args);
}
}
Observer.java
package garage.model;
public class Observer extends Thread {
public Platform platform;
static int count = 0;
{
setName("observer");
setPriority(MIN_PRIORITY);
setDaemon(true);
}
#Override
public void run() {
while (true) {
synchronized (Platform.lock) {
try {
System.out.println(++count);
platform.print();
Platform.lock.wait(5000); // hack for when there is no meaningful loop condition
} catch (InterruptedException exception) {
exception.printStackTrace();
} finally {
Platform.lock.notifyAll();
}
}
}
}
}
Vehicle run() method - relevant part
public void run() {
...
System.out.println("done");
}
MysteryVehicle run() method - relevant part
public void run() {
synchronized (Platform.lock) {
System.out.println("And the vehicle disappears!");
...
}
}
All of the relevant thread messages are printed out to the console.
done - 30 times, And the vehicle disappears!, before, after, END, true
This is the list of all of the running threads:
Attach Listener
main
Common-Cleaner
JavaFX Application Thread
Signal Dispatcher
Finalizer
InvokeLaterDispatcher
Reference Handler
QuantumRenderer-0
observer
Thread-2
JavaFX-Launcher
Since the program doesn't terminate and the print() function the run() method of observer calls is executed infinitely, what is it that prevents the daemon thread from terminating?
What am I missing here?
I suspect main() never returns, so the main thread (and perhaps some of those FX threads) are still running.
From the Application doc:
The launch method does not return until the application has exited,
either via a call to Platform.exit or all of the application windows
have been closed.
The posted code has no window to close nor is Platform.exit() invoked.
As far as I know, calling join on daemon thread is a bad idea.The idea behind using daemon thread is it will not halt JVM from exiting. What you can do is send an interrupt to that thread and call join after that.
I'm having a strange issue with multiple threads and breakpoints in IntelliJ IDEA 14.0.2. Code after the breakpoint is executed before it stops on it.
import java.util.concurrent.atomic.AtomicInteger;
public class Main {
private static final int NUM_CLIENTS = 1000;
static class TestRunnable implements Runnable {
AtomicInteger lock;
#Override
public void run() {
synchronized (this.lock) {
int curCounter = this.lock.addAndGet(1);
System.out.println("Thread: " + Thread.currentThread().getName() + "; Count: " + curCounter);
if (curCounter >= NUM_CLIENTS) {
lock.notifyAll();
}
}
}
}
public static void main(final String args[]) {
final AtomicInteger lock = new AtomicInteger(0);
for (int i = 0; i < NUM_CLIENTS; i++) {
TestRunnable tr1 = new TestRunnable();
tr1.lock = lock;
new Thread(tr1).start();
}
synchronized (lock) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("Main woken up");
}
}
}
When I put a breakpoint (Suspend All) at line 12, synchronized (this.lock), System.out.println still executes (sometimes several times). Here's a screenshot:
As far as I know, all threads should stop at the breakpoint.
The documentation reads confusingly, but this is the relevant block. What it distills down to is setting the property to suspend on threads, and not the entire application instead. This will cause you to hit the break point on each individual thread instead of an arbitrary, indeterminate thread.
Suspend Policy: All
When a breakpoint is hit, all threads are suspended.
Suspend Policy: Thread
When the breakpoint is hit, the thread where the breakpoint is hit is suspended.
Why doesn't thread wait for notify()? The thread starts and then goes to the waiting pool, but it proceeds to execute after that moment.
public class JavaApplication2 {
public static void main(String [] args) {
ThreadB b = new ThreadB();
synchronized(b) {
b.start();
try {
System.out.println("1");
b.wait();
} catch (InterruptedException e) {}
System.out.println("Total is: " + b.total);
}
}
}
class ThreadB extends Thread {
int total;
#Override
public void run() {
synchronized(this) {
total += 1;
//notify();
}
}
}
You are synchronizing on the thread object itself, which is wrong usage. What happens is that the dying thread-of-execution always calls notify on its Thread object: Thread.join relies on this. Therefore it is clear why you get the same behavior with and without your own notify in there.
Solution: use a separate object for thread coordination; this is the standard practice.
The method notifyAll() is invoked for the Thread object of the terminating thread. This fact is strangely documented in the description of the Thread.join, with the following sentence:
As a thread terminates the this.notifyAll method is invoked. It is recommended that applications not use wait, notify, or notifyAll on Thread instances.
Thus, if you don't explicitly read the description of join, which you don't necessarily have to, you don't get to know the reason for the strange behavior.
You cannot depend on not returning from wait until a notify: "interrupts and spurious wakeups are possible". In general, you should wrap a wait call in a loop while the thread should go on waiting.
If you try your code synchronizing on any object other that ThreadB you will find it never terminates. This is because there is a hidden call to notify.
Although I am not aware of anywhere that this is specified, Thread notifies itself when it ends. This is implicit in the way the join method is implemented. This is the code for join:
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
(From the JDK7 source code)
As you can see, the calls to wait only make sense if somewhere there is a call to notify that is called after the thread ends. The same call to notify is what allows your program to terminate.
You have nested synchronized {} constructs in the two places. These constructs seem doing something weird: the thread does not react into notify at all and only resumes when ThreadB (b) terminates. Remove this:
public class JavaApplication2 {
public static void main(String[] args) {
ThreadB b = new ThreadB();
b.start();
try {
System.out.println(" ### Waiting for notify");
synchronized (b) {
b.wait();
}
System.out.println(" ### Notified");
} catch (InterruptedException e) {
}
System.out.println("### Total is: " + b.total);
}
}
class ThreadB extends Thread {
int total;
#Override
public void run() {
total += 1;
System.out.println(" *** Ready to notify in 5 secs");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println(" *** Notification sent");
synchronized (this) {
notify();
}
System.out.println(" *** 5 sec post notification");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
}
System.out.println(" *** ThreadB exits");
}
}
The code above probably works correctly: with notify() present the main thread resumes after 5 seconds and before we see the message that ThreadB terminates. With notify() commented out the main thread resumes after 10 seconds and after the message about the termination of the ThreadB because notify() is called anywhay from the other code. Marko Topolnik explains why and from where this "behind the scene" notify() call comes from.
I was doing the same testing on the wait/notify opertaions while reading OCP SE 7, good catch. I think we should let the authoer to explain.
/*
This should always produce 0 as output since all three methods increment(), decrement(), value() are thread safe(synchronized). but it is returning 1
*/
class Counter implements Runnable {
private int c = 0;
public synchronized void increment() {
c++;
}
public synchronized void decrement() {
c--;
}
public synchronized int value() {
return c;
}
public void run() {
try {
this.increment();
Thread.sleep(1000);
this.decrement();
Thread.sleep(1000);
this.increment();
Thread.sleep(1000);
this.decrement();
Thread.sleep(1000);
}
catch (InterruptedException e){
return;
}
}
public static void main(String args[]) throws InterruptedException {
Counter c = new Counter();
new Thread(c).start();
new Thread(c).start();
System.out.println(c.value());
}
}
like everyone else said you need to make sure that the treads have finished executing, to do that you need to call join. for example
public static void main(String args[]) throws InterruptedException {
Counter c = new Counter();
Thread t1 = new Thread(c).start();
Thread t2 = new Thread(c).start();
t1.join();
t2.join();
System.out.println(c.value());
}
that should run correctly
There's nothing to control when the main thread is calling value(). It will run as soon as it can acquire a lock on c, even though the other threads are still running.
If you want to wait until the threads are done, call join() on them.
You are reading the value before the threads have finished execution, so it may be well different from zero.
You're not waiting for the threads to complete running, so the result is that the value of c is printed at whatever it is at that second. I bet if you tried it 1000 times, there would be times when it wasn't 1.
IBM has a fair tutorial on the situation you're encountering:
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/rzahw/rzahwex3rx.htm