Safe way to stop Java thread - java

Can anyone explain to me why the first thread doesn't work and the second works perfectly:
public class Test {
public static void main(String args[]) throws InterruptedException {
TestThread1 t1 = new TestThread1();
TestThread2 t2 = new TestThread2();
t1.startThread();
t2.start();
Thread.sleep(4000);
t1.stopThread();
t2.stopThread();
}
}
class TestThread1 extends Thread {
private volatile TestThread1 thread;
public void startThread() {
thread = new TestThread1();
thread.start();
}
public void run() {
while (thread != null) {
System.out.println("RUNNING 1 ...");
}
}
public void stopThread() {
thread = null;
}
}
class TestThread2 extends Thread {
private volatile boolean finished = false;
public void run() {
while (!finished) {
System.out.println("RUNNING 2 ...");
}
}
public void stopThread() {
finished = true;
}
}
When I debug inside TestThread1 class: Inside startThread, the thread member is filled (so it is not null), inside run, thread member is null!!! And finally, inside stopThread, the thread member is not null!!!
Can anyone explain to me what is happening here?

Here, you have two instances of TestThread1 t1:
One is stored into your t1 local variable (in your main method).
One is stored into your thread instance variable (of t1).
t1 is never started, t1.thread is.
t1.stopThread() sets t1.thread to null, but it doesn't affect t1.thread.thread.
Since you're starting t1.thread, its run method is using t1.thread.thread:
This is never set to anything (so it's using null).
Calling t1.stopThread() like you do would only set t1.thread to null, which wouldn't affect t1.thread.thread.
More generally, you can't just "kill" a thread as such, but you can implement tests within the method to tell it to return under certain circumstances. What you've done with your second test is closer to this (using while (!finished) { ... } with a volatile variable).
I wouldn't limit the test to finished. It's also useful to test whether the thread was interrupted, in particular because if you run your runnables within an ExecutorService shutdownNow() will try to interrupt them (see this question).
I'd use while (!finished && !Thread.currentThread().isInterrupted()) { ... }.
(Note the difference between Thread.currentThread().isInterrupted() and Thread.interrupted(): they may seem similar, but the latter will also reset the status, which you might not want.)
Depending on what's within your loop (or whether there is a loop at all), you may want to use something like if (finished || Thread.currentThread().isInterrupted()) { return; } at various strategic points, where it makes sense.

There is two TestThread1 object being created, one is started and the other is stopped.
I suggest not extending Thread and instead wrapping your Runnable once.

TestThread1 t1 = new TestThread1();
t1.startThread();
This will simply call method startThread() on object t1. Inside this method you are creating a new Thread.
thread = new TestThread1();
thread.start();
But for this Thread thread instance variable is null(It is not null for t1).
So in both cases thread variable should be null.

Because in your main method you create a Thread1 Object. You then run startThread which creates a different Thread1 object inside the first one and sets it to the field thread. You then start the second object which didn't have its own thread field initialized. When run method is run on the second object the condition is false and the while loop doesn't start.
Your object hierarchy looks something like this
t1 (Thread1) {
thread(Thread1): {
thread: null;
run() {
while (thread != null) {...} // this is the method that is run - thread is null here since you never initialized it
}
};
startThread() {} // calls the run method on the nested thread object above
run() {
while (thread != null) {...} // this method is not run since t1.start() is never called in main()
}
}

in your case,
t2.start();
is calling run method directly, it is not creating thread inside startThread method.
so t1.stopThread() makes the volatile thread inside Thread1 class null. so you are getting like that.
solution
use
t1.startThread();
t2.startThread();
instead of
t1.startThread();
t2.start();
which makes 2 threads to create separate threads inside that method.
if you want a single thread of Thread1 then use runnable interface and create 2 threads and call startThread respectively rather than creating extra threads inside main.

Related

Singleton with Java multithreading app

Briefly, I want to click on a button to run a background task (separated thread). I faced two problems:
What if user click many times on that button ==>Many thread will be
created.
Even if I use Singleton mechanism, I face another problem which is the fact that only one time that instance will be created even though after task accomplishes, user can't anymore re-run the process (second click on the button).
My class:
package mypack.check;
public class RunnableCheck implements Runnable {
private Thread t;
private static RunnableCheckFeeders instance;
public RunnableCheckFeeders getDefault() {
if (instance == null) {
instance = new RunnableCheckFeeders();
}
return instance;
}
#Override
public void run() {
//What the thread is supposed to do...
}
public void start() {
if (t == null) {
t = new Thread(this, "My task");
t.start();
}
}
}
In the caller class:
RunnableCheckFeeders.getDefault().start();
I tried with Synchronized methods but in vain, any proposition is welcome.
I suggest you use an ExecutorService.
enum RunOne {; // no instances
static final ExecutorService service = Executors.newSingleThreadedExecutor();
static Future last = null;
static synchronized void run(Runnable run) {
if (last != null && !last.isDone()) return;
last = service.submit(run);
}
}
This will submit a new task only if there is not already one running. It won't create more than one thread but you can submit tasks after a previous one finishes. You can call service.shutdown() to stop the service.
Your start method doesn't guarantee that only one "my task" thread will be created, even if there is only one instance of RunnableCheck: because the checking of the thread reference and subsequent assignment is not atomic, it is possible for two threads to be created and started if both happen to evaluate t == null to true at the same time (or, at least, a second thread can evaluate it to true before the first thread was able to assign a non-null value to t).
You can guard for this by:
Making the start method synchronized, so multiple threads cannot run the method at the same time;
Add an AtomicBoolean to record if the thread has been created/started. By updating the value of this flag atomically, it is not possible for two threads to set it to true, and thus impossible for two new Threads to be created and started:
private final AtomicBoolean started = new AtomicBoolean();
private Thread t;
public void start() {
if (!started.compareAndSet(false, true)) {
return;
}
t = new Thread(this, "My task");
t.start();
}
When a user clicks multiple times then do you want the event to happen multiple times, or just the once? If multiple times, you don't want a singleton, but rather to create a queue of work.
You can do this in one of two ways, the first is to use a a want a thread pool, likely using one from the ExecutorService.
Your second option is to have a single queue reading from a queue and a single thread reading from the queue.
If you want the event to only happen the once then you need to disable the button until it is completed, make start synchronized so only one thread can call it at a time and then set t to null once the thread finishes (i.e. the last item in run()).

Java: calling a method from the main thread by signaling in some way from another thread

I have an application with 2 threads (the main and another thread t1) which share a volatile variable myVar. Any ideas on how to make the main thread to call a method myMethod by signaling in some way from t1 ?
I implemented it by using ChangeListener and myMethod is called when myVar changes, BUT the method is called from t1, and not from the main thread (note: I need to call this method from the main thread because this is a call to a JavaScript code from Java, so for a security reason only the main thread can do so). Thanks in advance.
You would have to have your main thread spin in a loop on some scalar, I would recommend one of the Atomics that java provides (http://docs.oracle.com/javase/7/docs/api/java/util/concurrent/atomic/package-summary.html), but you could use volatile if you wanted for this I think.
Each thread can only run sequentially - it's just the way computing works. The way you will handle this, is when the main thread spins in some sort of loop, you eventually check to see if this scalar of yours has been set, and when it has, you want unset the variable and execute your JavaScript. In this particular piece of your code, I think the Atomics have an advantage over the volatile with the use of the compareAndSet operations because using volatile can mess you up a bit between threads if you are trying to check the value in one operation and then set it again in another operation which gives the other thread enough time to set it again - meaning you may miss a call to your JS because the other thread set the variable between the main thread checking it and setting it (although the use of volatile vs Atomics may be interpreted as my opinion).
//main thread
AtomicBoolean foo = new AtomicBoolean(false);
while (...somecondition...){
if(foo.compareAndSet(true, false)){
//execute JS
}
//do some other work
}
and in your T1 thread, just call foo.set(true).
If you expect main to call your JS for each time T1 sets foo to true, then you will have to block in T1 until main has unset foo, or use an AtomicInteger to count how many times T1 has set foo - depending on your needs.
Since both tread sharing the same instance of myVar, you can make both thread to synchronize on the shared variable. Have main to wait on myVar notification before executing myMethod. Later, t1 can notify through variable myVar, and the waiting thread can continue and proceed with the method call.
The following snippet fully demonstrated the idea
public class MainPlay {
public static void main(String[] args) {
MainPlay mp = new MainPlay();
mp.execute();
}
public void execute() {
Thread main = new Thread(mainRunnable, "main");
Thread t1 = new Thread(t1Runnable, "t1");
main.start();
t1.start();
}
public Object myVar = new Object();
public void myMethod() {
System.out.println("MyMethodInfoked.");
}
public Runnable t1Runnable = new Runnable() {
public void run() {
synchronized(myVar) {
try {
System.out.println("[t1] sleep for 1 sec");
Thread.sleep(1000);
System.out.println("[t1] Notifying myVar so Main can invoke myMethod");
myVar.notify();
} catch (InterruptedException e) {
// interupted.
}
}
}
};
public Runnable mainRunnable = new Runnable() {
public void run() {
synchronized(myVar) {
try {
System.out.println("[main] Waiting for t1 to notify...");
myVar.wait();
} catch (InterruptedException e) {
// interrupted.
}
System.out.println("[main] executing main method");
myMethod();
}
}
};
}
And the output is
[main] Waiting for t1 to notify...
[t1] sleep for 1 sec
[t1] Notifying sharedObject so Main can invoke myMethod
[main] executing main method
MyMethodInfoked.
You could use wait/notify blocks to prevent the main thread from continuing until signalled to do so.
static Main main = // ...
static boolean signal = false;
// t1:
// Do work
signal = true;
synchronized (main) {
main.notify();
}
// main:
synchronized (main) {
while (!signal) {
main.wait();
}
}
myMethod();
In case the main thread has nothing else to do, the approach proposed by #searchengine27 results in unnecessary processor load generated by this thread.
So instead going with some AtomicXXX class it would be better to use some of the blocking queues which allow writing of data from one thread (with put()) and consumption of that data by the other. The main queue would block (by calling take() method) if such a queue is empty not using any CPU resources.

Two thread which invokes wait and notify

The code I've witten doesn't work as I expected.
static Integer sync = 1;
static void m() throws Exception {
synchronized (sync) {
System.err.println("First");
sync.notify();
sync.wait(1000L);
System.err.println("Second");
System.err.println("Third");
}
}
public static void main(String[] args) throws Exception {
Runnable r = new Runnable() {
#Override
public void run() {
try {
m();
} catch (Exception ex) {
Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
Runnable t = new Runnable() {
#Override
public void run() {
try {
m();
} catch (Exception ex) {
Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
Thread th1 = new Thread(r);
Thread th2 = new Thread(t);
th1.run();
th2.run();
}
We have two threads which execute m()'s syncjronized statement. When the first thread executes one and come across the wait() it'll be added to the wait set. After this, the second thread is starting to execute the synchronized statement, and perform notify(). Since the output must be
First
First
....
But actually it is
First
Second
Third
First
Second
Third
Why?
First of all, your program is not creating any threads. You must call th1.start() and th2.start() to create threads.
t.start() is the method that the library provides for your code to call when you want to start a thread. run() is the method that you provide for the library to call in the new thread. Your run() method defines what the thread will do. IMO, run() was a really misleading name.
Second, notify() and wait() don't do what it looks like you think they will do. In particular, sync.notify() will not do anything at all if there are no other threads currently in sync.wait().
The correct way to use notify() and wait() is, one thread does this:
synchronized(lock) {
while (! someCondition()) {
lock.wait()
}
doSomethingThatRequiresSomeConditionToBeTrue();
}
The other thread does this
synchronized(lock) {
doSomethingThatMakesSomeConditionTrue();
lock.notify();
}
When you use this pattern, no thread should ever change the result of someCondition() except from inside a synchronized(lock) block.
Firstly, To actually create new threads please use
th1.start()
th2.start()
inplace of run() , which is just a regular method call on the thread object.
Secondly, it is possible that the second thread 'th2' did not start running by the time 1000 ms was fninshed , so the first thread finished wait(1000) and executed the remainging lines of code.
if you want the output like so :
first
first
second
third
second
third
then remove the time interval for wait() which will make the threads wait until notified.
as in :
static void m() throws Exception {
synchronized (sync) {
System.err.println("First");
sync.notify();
sync.wait();
System.err.println("Second");
System.err.println("Third");
}
}
Use .start() instead of run() to add runables to the queue instead of running them immediately
Documentation says that wait with timeout waits for any notify on this object or the timeout. In your case when runnables are being executed one by one it goes:
r: First
r: waits 1000ms and try to get lock
r: it already have access to lock object (exactly this code got lock) so continue
r: Second
r: Third
t: First, and so on ...
PS. calling run() and not setting timeout will cause deadlock on t's wait, cause it already has the object but will wait never be notified about it.
Hope this helps.

Why is this thread allowing another one to access its synchronized method?

I have the following codes. I expected one thread to execute its synchronized method completely and then allow another one to access the same method. However, this is not the case.
public class Threads {
/**
* #param args
*/
public static void main(String[] args) {
//Thread Th = new Threads();
Thread th = new Thread (new thread1 ());
th.start();
Thread th1 = new Thread (new thread1 ());
th1.start();
}
}
class thread1 implements Runnable{
String name = "vimal";
public void run() {
System.out.println("Runnable "+this.name);
setNAme("Manish");
}
public synchronized void setNAme(String name){
try {
System.out.println("Thread "+Thread.currentThread().getName());
wait(1000);
this.name = name;
System.out.println("Name "+this.name);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
I have one output as
Runnable vimal
Thread Thread-0
Runnable vimal
Thread Thread-1
Name Manish
Name Manish
What is the use of synchronized here and how do I make my method to run completely before another accesses it?
synchronized has no effect here because you are not synchronizing on the same object in both cases. When applied to an instance method, the synchronized keyword causes the method to be synchronized on this. So in each case you are synchronizing on the instance of thread1, and there are two of those.
The more interesting test would be when you run the same instance of thread1 in two threads simultaneously. In that case, calling wait(1000) is a very bad thing to do because (as documented) it releases the lock on this. You want to use Thread.sleep(1000) instead in your code.
If you need to have two instances of thread1, you need to synchronize on some shared object, possibly like this:
private static final Object lockObject = new Object();
public void setName(String newName) {
synchronized(lockObject) {
doSetName(newName);
}
}
You will have to remove the call to wait(1000). It looks like what you actually want is a call to Thread.sleep(1000), if you simply want to pause the current thread, this does not release ownership of any monitors.
From the javadoc for Object.wait().
This method causes the current thread (call it T) to place itself in
the wait set for this object and then to relinquish any and all
synchronization claims on this object. Thread T becomes disabled for
thread scheduling purposes and lies dormant until one of four things
happens:
Some other thread invokes the notify method for this object and thread T happens to be arbitrarily chosen as the thread to be
awakened.
Some other thread invokes the notifyAll method for this object.
Some other thread interrupts thread T.
The specified amount of real time has elapsed, more or less. If timeout is zero, however, then real time is not taken into
consideration and the thread simply waits until notified.
The thread T is then removed from the wait set for this object and
re-enabled for thread scheduling. It then competes in the usual manner
with other threads for the right to synchronize on the object; once it
has gained control of the object, all its synchronization claims on
the object are restored to the status quo ante - that is, to the
situation as of the time that the wait method was invoked. Thread T
then returns from the invocation of the wait method. Thus, on return
from the wait method, the synchronization state of the object and of
thread T is exactly as it was when the wait method was invoked.
UPDATE: As has been mentioned in other answers, you are not synchronizing on the same object. Once you do, you will still suffer the same output, due to the issue I have mentioned. You will need to fix both for your desired results.
The output is correct, you are creating to independent threads that do not share any data. Thus both threads start with first string, and after some time, the string is changed and printed.
You're creating 2 thread1 objects. They each have their own setNAme method. Synchronized methods only synchronize on the object, not the class. Unless the method is static.
You have two Threads here with independent name variables and independent monitors, so each Thread is only accessing its own members. If you want to have the threads interact with each other you'll have to implement such an interaction.
you are creating two separate thread1 objects and running them. Each thread has it's own copy of the name variable as well as the setName function. Make them both static and you will see the effects of synchronization.
You are locking on two different instance of the objects where you dont need any synchronization at all. You need to synchronize only if you are working on a shared data. I think you meant to write a test like the below.
If you test this, you will realize that the second thread will wait until the first thread is completed with the synchronized method. Then take out the synchronized word and you will see both threads are executing at the same time.
public class SynchronizeTest {
public static void main(String[] args) {
Data data = new Data();
Thread task1 = new Thread(new UpdateTask(data));
task1.start();
Thread task2 = new Thread(new UpdateTask(data));
task2.start();
}
}
class UpdateTask implements Runnable {
private Data data;
public UpdateTask(Data data) {
this.data = data;
}
public void run() {
try {
data.updateData();
} catch (Exception e) {
e.printStackTrace();
}
}
}
class Data {
public synchronized void updateData() throws InterruptedException {
for (int i = 0; i < 5; i++) {
Thread.sleep(5000);
System.out.println(i);
}
}
}

How does a Java thread behave when a method is accessed externally?

Suppose I have the following thread:
public class MyThread {
public void run() {
while (true) {
// do something forever
}
}
}
Then I instantiate the thread as follows:
MyThread thread = new MyThread();
What happens if I now call
thread.performSomeFunction()
Specifically, how does performSomeFunction interact with the infinite loop above? Does it have to wait for the loop to sleep? Or can they both run "concurrently"?
If your thread.performSomeFunction() is called from another thread, it does not have to contend with the infinite loop that is being run in the run() method. In this case, your MyThread instance is treated like another object that can have methods called on it.
Note that your infinite loop will not start until you start your thread instance.
You can test this out by putting the following line in both the run() method and your perfomrSomeFunction() method:
System.out.println("in [METHOD NAME]: " + Thread.currentThread().getName());
and replace the [METHOD NAME] with the actual method name.

Categories