Synchronizing threads in java - java

Good day!
I got the problem about synchronizing threads in java. I am developing program which creates timers and allows to reset it, delete and stop. Just to learn how to using threads.
The problem is that code gives synchronizing only for some time... I can't understand my mistake. Maybe my way is wrong so i would like to know how to solve this issue.
I have next code:
public class StopWatch
{
//Create and start our timer
public synchronized void startClock( final int id )
{
//Creating new thread.
thisThread = new Thread()
{
#Override
public void run()
{
try
{
while( true )
{
System.out.printf( "Thread [%d] = %d\n", id, timerTime );
timerTime += DELAY; //Count 100 ms
Thread.sleep( DELAY );
}
}
catch( InterruptedException ex )
{
ex.printStackTrace();
}
}
};
thisThread.start();
}
…
//Starting value of timer
private long timerTime = 0;
//Number of ms to add and sleep
private static final int DELAY = 100;
private Thread thisThread;
}
I call this Class like:
StopWatch s = new StopWatch(1);
s.startClock();
StopWatch s2 = new StopWatch(2);
s2.startClock();

I think you may have misunderstood "synchronized".
It does not mean that the threads run in exactly synchronized time - rather that only one thread at a time is allowed to be executing the synchronized code block. In your case "synchronized" makes no difference, since you are calling the startClock method from the same thread....
In general, it is impossible in Java (and indeed most high level languages) to guarantee that two threads perform actions at exactly the same clock time even if you have multiple cores, since they are always vulnerable to being delayed by the OS scheduler or JVM garbage collection pauses etc.
Also, Thread.sleep(...) is unreliable as a timing mechanism, as the amount it sleeps for is only approximate. You're at the mercy of the thread scheduler.
Suggested solution:
use System.currentTimeMillis() if you want a thread-independent timing mechansim.

What do you mean it "only gives you synchronizing for some time?" The only thing you have synchronized here is the startClock method, which just means that two threads will not be within that method at the same time (and it doesn't look like you are doing that anyway). If you wanted to synchronize access to timerTime for example, you would need to put a synchronized block inside thread run method around the incrementing timerTime (or you could use an AtomicLong).

You should probably re-read the documentation for the "synchronize" keyword. I'm pretty sure in this case all it would do is keep the two calls of StartClock() from executing at the same time, which wouldn't happen given this code because they're called one after the other from one thread. Once the timer thread begins, there's nothing keeping them synchronized, if that's your goal.

Your first problem is that this is a time based only solution. This is bad because the program has no control over how long it takes to execute. Some operations take more time than others and each thread within your process doesn't execute at the same time. In general this won't synchronize anything unless you can guarantee everything else is the same . . .
Read about http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Semaphore.html and you can also do
Thread.join(); to make the main loop wait for the execution of the child thread to finish before continuing execution.

I think you misunderstood what synchronized means. Synchronized is to ensure that multiple threads have limited access to a certain block of code so that you don't get conflicts between the two threads.
I think what you may be more interested in is a CyclicBarrier or a CountDownLatch. Both can be used to "synchronize" (overloaded use in this case) multiple threads so that they try to start doing things at the same time.
However, be aware that it's impossible to have multiple threads do things at exactly the same instant. You can only try to encourage to do them at about the same time. The rest is subject to OS scheduling on the cores in the system. And if you have a single core, they will never run at the same time.

Related

How can I brutally and mercilessly abort a task in Java?

I programmed a sudoku solver in Java for a homework, and I am currently trying to figure out the problematic inputs it can face to make it better. I have generated a few thousand sudoku grids with David Bau's sudoku generator, and now I am running my program against them.
The problem is that while most of them complete in very reasonable times, some of them prove to be problematic and make my algorithm search like crazy until I run out of heap space. So I thought I should offshore the solving job to a secondary thread and run it with a timeout. Right now, I'm using a thread 'pool' of one thread (in the form of an ExecutorService) and I'm submitting Callables to it. I then try to get the value with a timeout:
Callable<Long> solveAndReturnTime = new Callable<Long>() { /* snip */ };
Future<Long> time = executor.submit(solveAndReturnTime);
try
{
long result = time.get(10, TimeUnit.SECONDS);
System.out.printf("%d millis\n", result);
}
catch (TimeoutException e)
{
System.err.println("timed out");
time.cancel(true);
}
My problem is that apparently, one does not simply cancel a Future in Java. Future<T>.cancel(boolean) apparently doesn't interrupt the task right away. Because of that, the pool is stuck with carrying an undying task, and the subsequent attempts timeout because they never get a chance to run.
Adding more threads to the pool is not an option because I run on limited cores and if too many tasks obstinately run, the legitimate ones will be unfairly slowed down. I also don't want the overhead of frequently checking if the task was aborted from my main algorithm.
How can I abruptly, mercilessly and brutally terminate a task? I'm open to anything that will let me recover on the main thread.
EDIT My algorithm is completely sequential, uses no global object, and contains no lock. As far as I can tell, nothing will go wrong if the task is cancelled at a random moment; and even if it does, it's not production code. I'm ready to walk the dangerous and treacherous walk for this one.
Just as in any other language methods to mercifully terminate a thread are Deprecated or not recommended. Because such methods may cause deadlocks (a thread being terminated will not release the locks it's holding).
The correct solution to the problem is having an additional check for Thread.currentThread ().isInterrupted () on every iteration of the main cycle in you Callable. So when the thread is being interrupted it would see it and gracefully shut down.
And since it's you code running in another thread it shouldn't be difficult for you to modify it.
In addition to Andrei's answer, which is correct, you should be aware that doing this work in a thread will not protect your application from running out of memory via an OOM. If your worker thread consumes the entire heap, the main thread can very well die too.
I believe my case was 'special' enough to use Thread.stop, so here is my solution to the people who believe their case is special enough too. (I would take extreme care using that somewhere it could actually matter, though.)
As mostly everyone points out, there's no clean way to stop a task without having that task check if it should stop itself. I created a class that implements Runnable to carry out in such a way that it won't be dramatic if it's killed. The result field (milliseconds) is an AtomicLong because writes on regular long variables are not guaranteed to be atomic.
class SolveTimer implements Runnable
{
private String buildData;
private AtomicLong milliseconds = new AtomicLong(-1);
public SolveTimer(String buildData)
{
assert buildData != null;
this.buildData = buildData;
}
public void run()
{
long time = System.currentTimeMillis();
// create the grid, solve the grid
milliseconds.set(System.currentTimeMillis() - time);
}
public long getDuration() throws ContradictionException
{
return milliseconds.get();
}
}
My code creates a thread on each iteration and runs a SolveTimer. It then attempts to join within 10 seconds. After join returns, the main thread calls getDuration on the run timer; if it returns -1, then the task is taking too long and the thread is killed.
SolveTimer timer = new SolveTimer(buildData);
Thread worker = new Thread(timer);
worker.start();
worker.join(10000);
long result = timer.getDuration();
if (result == -1)
{
System.err.println("Unable to solve");
worker.stop();
}
It should be noted that this makes worker threads harder to debug: when the thread is suspended by the debugger, it can still be killed by Thread.stop(). On my machine, this writes a short error message about ThreadDeath in the console and crashes the Java process.
There is a possible race condition where the worker thread completes exactly (or right after) getDuration is called, and because of that result will be -1 even if the task actually succeeded. However, that's something I can live with: 10 seconds is already far too long, so at that point I don't really care anymore if it's nearly good enough.

Terminated Thread Revival

I am storing a bunch of threads objects in an arraylist. I want to be able to start these threads at random. Same thread can be started more than once. Before I start a thread object, I check on whether the thread is alive, and if they have either of NEW or TERMINATED status. This restriction because, I don't want to disturb the 'busy' threads. Now, for NEW threads, this works fine. But for TERMINATED thread, I get an exception.
When a thread ends, shouldn't it go back to being 'new'? Or are threads 'disposable' - like use once and done?
As it says in the documentation for Thread.start(), "It is never legal to start a thread more than once. In particular, a thread may not be restarted once it has completed execution."
It is better for you to keep hold of Runnable instances and implement your own logic for keeping track of when the execution of each one of them finishes. Using an Executor is probably the simplest way to run the Runnables.
You should probably be using the awesome stuff provided in java.util.concurrent. Based on your description, ThreadPoolExecutor sounds like a good thing to check out.
This is the way I did it
class GarbageDisposalThread extends Thread {
public void start() {
try {
super.start();
} catch( IllegalThreadStateException e ) {
this.arrayList.remove(this);
this.arrayList.add( new GarbageDisposalThread( this.arrayList ));
}
}
private GarbageDisposalThread() {
}
public GarbageDisposalThread( ArrayList<Whatever> arrayList ) {
this.arrayList = arrayList;
this.start();
}
public void run() {
// whatever the code
}
private ArrayList<Whatever> arrayList = null;
}
that's it!
you can change the code according to your needs :P
Java threads cannot be restarted.
From the javadoc:
It is never legal to start a thread
more than once. In particular, a
thread may not be restarted once it
has completed execution.
See the Thread.start() javadoc for more information.
There are other ways to accomplish what you are trying to do. For example, you could use new Threads that continue the work that was done in the Thread that has finished execution. You may also want to investigate the java.util.concurrent package.
From another post...
You could use ThreadPoolExecutor, which would allow you to pass in tasks and let the service assign a thread to a task. When the task is finished, the thread goes idle until it gets the next task.
So, you don't restart a thread, but you would redo/resume a task.

stop a thread in java after a given time - doesn't work

I have a complex function (optimisation) that can potentially enter in a loop or just to take too much time, and the time allowed is set by the user.
Therefore I am trying to make to run the function in a separate thread, and to stop it if the maximum time is passed. I use a code similar to the one below, but it doesn't work, so
int timeMax = 2; //time in minutes
Thread Thread_Object = new Thread_Class(... args...);
try {
Thread_Object.start();
Thread_Object.join(timeMax*60*1000);
}
I think that I'm not using the function "join" properly, or it doesn't do what I have understood. Any idea?
Thanks!
Thanks for the answers, currently I have found a better idea here*. It works but it still uses the function "stop" that is deprecated. The new code is:
Thread Thread_Object = new Thread_Class(... args...);
try {
int timeMax = 1;
Thread_Object.start();
Thread.currentThread().sleep( timeMax * 1000 );
if ( Thread_Object.isAlive() ) {
Thread_Object.stop();
Thread_Object.join();
}
}
catch (InterruptedException e) {
}
not yet sure of the function of "join", I'll have to go to have a look at some book.
java scripting API - how to stop the evaluation
I suggest you use a Timer.
The join method will wait the current thread until the thread that is being joined on finishes. The join with milliseconds passed in as a parameter will wait for some amount of time, if the time elapses notify the waiting thread and return.
What you can do, is after the join completes interrupt the thread you joined on. Of course this requires your thread to be responsive to thread interruption.
Thread.join(milis) does not kill the thread. It just waits for the thread to end.
Java threading is cooperative: you can not stop or gracefully kill a thread without it's cooperation. One way to do it is to have an atomic flag (boolean field) that thread is checking and exiting if set.
Watchdog-Timers in Java are not a simple thing, since threading is cooperative. I remember that in one project we just used Thread.stop() although it is deprecated, but there was no elegant solution. We didn't face any issues using it, though.
A good example for a Java Watchdog implementation:
http://everything2.com/user/Pyrogenic/writeups/Watchdog+timer
This might be useful
http://tempus-fugit.googlecode.com/svn/site/documentation/concurrency.html#Scheduled_Interruption

Java: Stopping a thread that has run for too long?

Say I've got something like this
public void run(){
Thread behaviourThread = new Thread(abstractBehaviours[i]);
behaviourThread.start();
}
And I want to wait until abstractBehaviours[i] run method has either finished or run for 5000 milliseconds. How do I do that? behaviourThread.join(5000) doesn't seem to do that afaik (something is wrong with my code and I've put it down to that).
All the abstract abstractBehaviour class is of course Runnable. I don't want to implement it inside each run method as that seems ugly and there are many different behaviours, I'd much rather have it in the calling/executing thread and do it just once.
Solutions? First time doing something as threaded as this. Thanks!
edit: So the interrupting solution would be ideal (requiring minimal changes to AbstractBehaviour implementations). BUT I need the thread to stop if it has finished OR 5000 milliseconds have passed so something like the following would not work because the thread may finish before the while loop in the parent thread has. Make sense? Any ways around this, I'd love to do it from within the thread that starts the threads obviously.
long startTime = System.currentTimeMillis();
behaviourThread.start();
while(!System.currentTimeMilis - startTime < 5000);
behaviourThread.interrupt();
try {
behaviourThread.join();
} catch (InterruptedException e1) {
e1.printStackTrace();
}
edit: nevermind I see there is a Thread.isAlive() method, all solved I think
The best way to do this is to use the thread interrupt mechanism. The worker thread / Runnable needs to periodically call Thread.interrupted() to see if it is time to stop. The second part of the equation is that a separate thread needs to call Thread.interrupt() on the worker thread after 5000 milliseconds have elapsed.
The advantages of using thread interrupts (over a bespoke solution using flags) include:
The interrupted() state is always available for the current thread. You don't need to pass around an object handle or use a singleton.
An interrupt will unblock some blocking IO and synchronization requests. A bespoke solution cannot do this.
Third-party Java applications and libraries may respect Thread.interrupt().
EDIT - as a commenter points out, you can test whether the current thread has been interrupted using either Thread.interrupted() or Thread.currentThread().isInterrupted(). The main difference between the two approaches is that the former clears the interrupted flag, but the latter doesn't.
You cannot do this externally from the run method - the run method must check some variable to see if it should exit. For example:
class InterruptableRunnable implements Runnable
{
private volatile boolean stop;
public setStop() {
stop = true;
}
public void run() {
while (!stop)
{
//do some work and occassionaly fall through to check that stop is still true
}
}
}
The key thing is for the code in the run loop to check the stop flag occasionally. You can then wire up a timer to set stop to true after 5000 milliseconds.
Finally, it's best practice not to use Threads directly, use the excellent Concurrency Framework. The Concurrency Tutorial is a good place to start and the book Java Concurrency in practice is excellent.
You may do it using java.util.concurrent package.
ExecutorService service = Executors.newCachedThreadPool();
Future future = service.submit(behaviourThread);
long startTime = System.currentTimeMillis();
while (!future.isDone()) {
if (System.currentTimeMillis() - startTime > 5000) {
future.cancel(true);
break;
}
}
// TODO: more work here
//don't forget to shutDown your ThreadPool
service.shutDown();
This code will stop your thread after 5 seconds if it has not finished it's job by that time. If you check behaviourThread.isAlive() it's gonna show false.
You do that by implementing a Runnable
public void run()
{
long time = System.nanoTime(),
end = time + 5 000 000 000; // just better formatting
do {
...my code
} while (System.nanoTime() < end && myOwnCondition);
}
Interrupt is not such a good solution, because you need to access the thread from outside
and it disturbs the program flow. The thread can terminate anytime in your code which
makes cleanup difficult. Please form a habit of letting threads run to the end because otherwise it opens nasty and difficult bugs.
If your program is so heavy duty that you don't know that the while end is reached until the task has completed I suggest the use of a labeled break:
do {
breakout:
{
..my code
if (timetest)
break breakout;
}
// cleanup
...
} while (...);

How can you ensure in java that a block of code can not be interrupted by any other thread

exampl:
new Thread(new Runnable() {
public void run() {
while(condition) {
*code that must not be interrupted*
*some more code*
}
}
}).start();
SomeOtherThread.start();
YetAntherThread.start();
How can you ensure that code that must not be interrupted won't be interrupted?
You can't - at least not with normal Java, running on a normal, non-real-time operating system. Even if other threads don't interrupt yours, other processes might well do so. Basically you won't be able to guarantee that you get a CPU all to yourself until you're done. If you want this sort of guarantee you should use something like Java Real-Time System. I don't know enough about it to know whether that would definitely provide the facility you want though.
The best thing to do is avoid that requirement in the first place.
Assuming you're only concerned with application-level thread contention, and assuming you are willing to fuss with locks as suggested by others (which, IMHO, is a really bad idea), then you should use a ReadWriteLock and not simple object synchronization:
import java.java.util.concurrent.locks.*;
// create a fair read/write lock
final ReadWriteLock rwLock = new ReentrantReadWriteLock(true);
// the main thread grabs the write lock to exclude other threads
final Lock writeLock = rwLock.writeLock();
// All other threads hold the read lock whenever they do
// *anything* to make sure the writer is exclusive when
// it is running. NOTE: the other threads must also
// occasionally *drop* the lock so the writer has a chance
// to run!
final Lock readLock = rwLock.readLock();
new Thread(new Runnable() {
public void run() {
while(condition) {
writeLock.lock();
try {
*code that must not be interrupted*
} finally {
writeLock.unlock();
}
*some more code*
}
}
}).start();
new SomeOtherThread(readLock).start();
new YetAntherThread(readLock).start();
Actually, you can do this if you control the thread instance you are running on. Obviously, there are a ton of caveats on this (like hanging io operations), but essentially you can subclass Thread and override the interrupt() method. you can then put some sort of boolean in place such that when you flip a flag, interrupt() calls on your thread are either ignored or better yet stored for later.
You really need to leave more info.
You cannot stop other system processes from executing unless you run on a real-time OS. Is that what you mean?
You cannot stop garbage collection, etc unless you run a real-time java. Is that what you wanted?
The only thing left is: If you simply want all YOUR other java threads to not interrupt each other because they all tend to access some resource willy-nilly without control, you are doing it wrong. Design it correctly so that objects/data that NEED to be accessed in a synchronized manner are synchronized then don't worry about other threads interrupting you because your synchronized objects are safe.
Did I miss any possible cases?
Using the synchronized approach ( in the various forms posted here ) doesn't help at all.
That approach only helps to make sure that one thread executes the critical section at a time, but this is not what you want. You need to to prevent the thread from being interrupted.
The read/write lock seems to help, but makes no difference since no other thread is attempting to use the write lock.
It only makes the application a little slower because the JVM has to perform extra validations to execute the synchronized section ( used only by one thread , thus a waste of CPU )
Actually in the way you have it, the thread is not "really" being interrupted. But it seems like it does, because it has to yield CPU time to other threads. The way threads works is; the CPU gives to each thread a chance to run for a little while for very shorts periods of time. Even one when a single thread running, that thread is yielding CPU time with other threads of other applications ( Assuming a single processor machine to keep the discussion simple ).
That's probably the reason it seems to you like the thread is being paused/interrupted from time to time, because the system is letting each thread in the app run for a little while.
So, what can you do?
To increase the perception of no interruptions, one thing you can do is assign a higher priority to your thread and decrease it for the rest.
If all the threads have the same priority one possible schedule of threads 1,2,3 could be like this:
evenly distributed
1,2,3,1,2,3,1,2,3,1,2,3,1,2,3,1,2,3
While setting max for 1, and min for 2,3 it could be like this:
More cpu to thread 1
1,1,1,2,1,1,3,1,1,1,2,1,1,1,3,1,2,1,1,1
For a thread to be interrupted by another thread, it has to be in an interruptable state, achieved by calling, Object.wait, Thread.join, or Thread.sleep
Below some amusing code to experiment.
Code 1: Test how to change the priority of the threads. See the patterns on the ouput.
public class Test {
public static void main( String [] args ) throws InterruptedException {
Thread one = new Thread(){
public void run(){
while ( true ) {
System.out.println("eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee");
}
}
};
Thread two = new Thread(){
public void run(){
while ( true ) {
System.out.println(".............................................");
}
}
};
Thread three = new Thread(){
public void run(){
while ( true ) {
System.out.println("------------------------------------------");
}
}
};
// Try uncommenting this one by one and see the difference.
//one.setPriority( Thread.MAX_PRIORITY );
//two.setPriority( Thread.MIN_PRIORITY );
//three.setPriority( Thread.MIN_PRIORITY );
one.start();
two.start();
three.start();
// The code below makes no difference
// because "one" is not interruptable
Thread.sleep( 10000 ); // This is the "main" thread, letting the others thread run for aprox 10 secs.
one.interrupt(); // Nice try though.
}
}
Code 2. Sample of how can be a thread actually be interrupted ( while sleeping in this case )
public class X{
public static void main( String [] args ) throws InterruptedException {
Thread a = new Thread(){
public void run(){
int i = 1 ;
while ( true ){
if ( i++ % 100 == 0 ) try {
System.out.println("Sleeping...");
Thread.sleep(500);
} catch ( InterruptedException ie ) {
System.out.println( "I was interrpted from my sleep. We all shall die!! " );
System.exit(0);
}
System.out.print("E,");
}
}
};
a.start();
Thread.sleep( 3000 ); // Main thread letting run "a" for 3 secs.
a.interrupt(); // It will succeed only if the thread is in an interruptable state
}
}
Before a thread is interrupted, security manager's checkAccess() method is called.
Implement your own security manager, call System.setSecurityManager to install it and make sure it doesn't let any other thread interrupt you while it is in critical section.
Error processing is an example of a use case where it is very useful to stop threads from being interrupted. Say you have a large multi-threaded server and some external condition arises that causes errors to be detected on multiple worker threads simultaneously. Each worker thread generates a notification that an error occurred. Let's say further the desired response is to bring the server to a safe state that will allow it to restart after the error condition is cleared.
One way to implement this behavior is to have a state machine for the server that processes state changes in total order. Once an error notification arrives, you put it into the state machine and let the state machine process it in toto without interruption. This is where you want to avoid interruptions--you want the first notification to cause the error handler to run. Further notifications should not interrupt or restart it. This sounds easy but really isn't--suppose the state machine was putting the server online. You would want to interrupt that to let error processing run instead. So some things are interruptible but others are not.
If you interrupt the error processing thread it may blow the error handler out of the water during synchronized method processing, leaving objects in a potentially dirty state. This is the crux of the problem--thread interrupts go around the normal synchronization mechanism in Java.
This situation is rare in normal applications. However, when it does arise the result can be byzantine failures that are very difficult to anticipate let alone cure. The answer is to protect such critical sections from interrupts.
Java does not as far as I can tell give you a mechanism to stop a thread from being interrupted. Even if it did, you probably would not want to use it because the interrupt could easily occur in low-level libraries (e.g., TCP/IP socket processing) where the effect of turning off interrupts can be very unpredictable.
Instead, it seems as if the best way to handle this is to design your application in such a way that such interrupts do not occur. I am the author of a small state machine package called Tungsten FSM (https://code.google.com/p/tungsten-fsm). FSM implements a simple finite-state machine that ensures events are processed in total order. I'm currently working on a bug fix that addresses exactly the problem described here. FSM will offer one way to address this problem but there are many others. I suspect most of them involve some sort of state machine and/or event queue.
If you take the approach of preventing interruptions it of course creates another problem if non-interruptible threads become blocked for some reason. At that point you are simply stuck and have to restart the process. It does not seem all that different from a deadlock between Java threads, which is in fact one way non-interruptible threads can become blocked. There's really no free lunch on these types of issues in Java.
I have spent a lot of time looking at problems like this--they are very difficult to diagnose let alone solve. Java does not really handle this kind of concurrency problem very well at all. It would be great to hear about better approaches.
Just start your own sub-thread, and make sure that the interrupt calls never filter through to it.
new Thread(new Runnable() {
public void run() {
Thread t = new Thread() {
public void run() {
*code that must not be interrupted*
}
}
t.start(); //Nothing else holds a reference to t, so nothing call call interrupt() on it, except for your own code inside t, or malicious code that gets a list of every live thread and interrupts it.
while( t.isAlive() ) {
try {
t.join();
} catch( InterruptedException e ) {
//Nope, I'm busy.
}
}
*some more code*
}
}
}).start();
SomeOtherThread.start();
YetAntherThread.start();
I think you need to lock on an interrupt flag. What about something like this (not tested):
new Thread() {
boolean[] allowInterrupts = { true };
#Override
public void run() {
while(condition) {
allowInterrupts[0] = false;
*code that must not be interrupted*
allowInterrupts[0] = true;
*some more code*
}
}
#Override
public void interrupt() {
synchronized (allowInterrupts) {
if (allowInterrupts[0]) {
super.interrupt();
}
}
}
}.start();
SomeOtherThread.start();
YetAntherThread.start();
Best halfway solution would be to synchronize all threads on some common object so that no other threads are runnable while you're in the critical section.
Other than that I do not think it's possible. And I'm quite curious as to what kind of problem that requires this type of solution ?
A usual program does not randomly interrupt threads. So if you start a new Thread and you are not passing the reference to this Thread around, you can be quite sure that nothing will interrupt that Thread.
Keep the reference to the Thread private is sufficient in most scenarios. Everything else would be hacky.
Typically work queues like ExecutorService will interrupt their Thread's when asked to do so. In these cases you want to deal with interrupts.

Categories