I tried to make a event dispatcher in Java that will dispatch events as threads. So all the EventListener classes are essentially implemented the Runnable class. Like how firing of events work traditionally, a method in the event dispatcher class loops through a list of EventListeners and then invoke their handler method, except that this time, I invoke these handler as threads by putting the listeners into new Thread(handlerObject).start(). The actual handling is done in the run() method in the EventListener.
So it looks something like:
for(EventListener listener : listenerList) {
if(listener instanceof Runnable)
new Thread(listener).start();
}
So all instructions to handle the event in the listener are put inside the run() method, which will be executed when the thread.start().
But the problem is the threads often go into a situation where one of the threads got stuck somewhere and didn't manage to continue. Sometimes, several threads may also get stuck while some managed to run through all instructions in the run() method in the listener. I looked up and this sounds like what it is called a deadlock.
I tried to put the "synchronized" modifier to all my methods but it still has this problem. I thought the synchronized keyword would simply just queue any threads trying to run a similar method until a current thread running the method has finished. But this doesn't solve the problem still. Why doesn't synchronized solve the problem especially when I already have it on all my methods and it should queue any concurrent access that may potentially cause a deadlock? I didn't use any wait() or notify() methods. Just a simple event dispatcher that attempts to run its event listener as a thread.
I am pretty new to threads but have found it very difficult to even debug it because I don't know where has gone wrong.
Thanks for any help.
Deadlock is something along the lines of this:
A needs iron to make tools, asks B for
iron
B needs tools to make iron,
asks A for tools
Neither will complete. Just because you've put the syncronized key word around them does not guarantee that you're going to run into a logical impossibility. You have to judge when one thing will be able to move forward and when it won't.
Never just add synchronized to all methods, this solves nothing - you will effectively make your program single-threaded.
When you think you have a deadlock, you can take a thread dump and analyze the output to understand what each thread is executing, which locks (if any) they are holding, what locks they are waiting for, etc.
Unfortunately without specific code or understanding the actual synchronization going on in your application, the only advice that can be given is general like this.
I don't know what you mean by 'deadlock despite synchronized keyword'. The `synchronized' keyword doesn't prevent deadlocks. It can cause them, if you have two threads that acquire locks in different orders. Solution: don't.
Your real problem is that you don't understand concurrency well enough to understand why your program is not working, let alone how to solve this. (FWIW - adding synchronized to all of your methods is only making the problem worse.)
I think that your best plan is take time out to do some reading on concurrency in Java. Here are a couple of good references:
The Java Concurrency Tutorial Stream.
Java Concurrency in Practice by Brian Goetz et al.
#wheaties has a micro-explanation of what a deadlock is, and #matt_b offers useful advice on how to diagnose a deadlock. However, these won't help a lot unless you know the right way to design and write your multi-threaded code.
Related
Synchronization works by providing exclusive access to an object or method by putting a Synchronized keyword before a method name. What if I want to give higher precedence to one particular access if two or more accesses to a method occurs at the same time. Can we do that?
Or just may be I'm misunderstanding the concept of Synchronization in java. Please correct me.
I have other questions as well,
Under what requirements should we make method synchronized?
When to make method synchronized ? And when to make block synchronized ?
Also if we make a method synchronized will the class too be synchronized ? little confused here.
Please Help. Thanks.
No. Sadly Java synchronization and wait/notify appear to have been copied from the very poor example of Unix, rather than almost anywhere else where there would have been priority queues instead of thundering herds. When Per Brinch Hansen, author of monitors and Objective Pascal, saw Java, he commented 'clearly I have laboured in vain'.
There is a solution for almost everything you need in multi-threading and synchronization in the concurrent package, it however requires some thinking about what you do first. The synchronized, wait and notify constructs are like the most basic tools if you have just a very basic problem to solve, but realistically most advanced programs will (/should) never use those and instead rely on the tools available in the Concurrent package.
The way you think about threads is slightly wrong. There is no such thing as a more important thread, there is only a more important task. This is why Java clearly distinguishes between Threads, Runnables and Callables.
Synchronization is a concept to prevent more than one thread from entering a specific part of code, which is - again - the most basic concept of avoiding threading issues. Those issues happen if more than one thread accesses some data, where at least one of those multiple threads is trying to modify that data. Think about an array that is read by Thread A, while it is written by Thread B at the same time. Eventually Thread B will write the cell that Thread A is just about to read. Now as the order of execution of threads is undefined, it is as well undefined whether Thread A will read the old value, the new value or something messed up in between.
A synchronized "lock" around this access is a very brute way of ensuring that this will never happen, more sophisticated tools are available in the concurrent package like the CopyOnWriteArray, that seamlessly handles the above issue by creating a copy for the writing thread, so neither Thread A nor Thread B needs to wait. Other tools are available for other solutions and problems.
If you dig a bit into the available tools you soon learn that they are highly sophisticated, and the difficulties using them is usually located with the programmer and not with the tools, because countless hours of thinking, improving and testing has been gone into those.
Edit: to clarify a bit why the importance is on the task even though you set it on the thread:
Imagine a street with 3 lanes that narrows to 1 lane (synchronized block) and 5 cars (threads) are arriving. Let's further assume there is one person (the car scheduler) that has to define which cars get the first row and which ones get the other rows. As there is only 1 lane, he can at best assign 1 cars to the first row and the others need to come behind. If all cars look the same, he will most likely assign the order more or less randomly, while a car already in front might stay in front more likely, just because it would be to troublesome to move those cars around.
Now lets say one car has a sign on top "President of the USA inside", so the scheduler will most likely give that car priority in his decision. But even though the sign is on the car, the reason for his decision is not the importance of the car (thread), but the importance on the people inside (task). So the sign is nothing but an information for the scheduler, that this car transports more important people. Whether or not this is true however, the scheduler can't say (at least not without inspection), so he just has to trust the sign on the car.
Now if in another scenario all 5 cars have the "President inside" sign, the scheduler doesn't have any way to decide which one goes first, and he is in the same situation again as he was with all the cars having no sign at all.
Well in case of synchronized, the access is random if multiple threads are waiting for the lock. But in case you need first-come first-serve basis: Then you can probably use `ReentrantLock(fairness). This is what the api says:
The constructor for this class accepts an optional fairness parameter.
When set true, under contention, locks favor granting access to the
longest-waiting thread.
Else if you wish to give access based on some other factor, then I guess it shouldn;t be complicated to build one. Have a class that when call's lock gets blocked if some other thread is executing. When called unlock it will unblock a thread based on whatever algorithm you wish to.
There's no such thing as "priority" among synchronized methods/blocks or accesses to them. If some other thread is already holding the object's monitor (i.e. if another synchronized method or synchronized (this) {} block is in progress and hasn't relinquished the monitor by a call to this.wait()), all other threads will have to wait until it's done.
There are classes in the java.util.concurrent package that might be able to help you if used correctly, such as priority queues. Full guidance on how to use them correctly is probably beyond the scope of this question - you should probably read a decent tutorial to start with.
I was wondering if there is some way in Java to stop thread immediately. I don't want to check its interrupted status, I need to stop it immediately. That's because in thread's run method there are many calculations and to achieve what I want using interrupted I would have to inject status check everywhere. So is there some way to interrupt thread immediately? Maybe stop() method? I know it's is said it shouldn't be used because of deadlocks but if it could solve my problem (even if it would cause another ;) ) I could use it. So? P.S. I know there were other, similar questions but everywhere people give similar questions to interrupted() which doesn't suit me.
The question/answer that #Alya'aGamal points to is the right one.
If your app's design assumes that forcibly stopping a thread, or a process, or a program (like using kill -9 or stopping it via the Task Manager on Windows) is an okay thing to do, then you really need to justify that, because it sounds like a bad design choice. If you used someone else's app and the only way to close it on demand was to forcibly stop it, wouldn't you think that was a rather major flaw?
If you have long-running loops or algorithms and it's important to be able to stop them at an arbitrary point then you MUST put some kind of regular status or signal check in place in order to do this properly.
Always design your apps in a way such that there is a nice, friendly, graceful way for them to exit from all situations other than things outside your control (e.g. another app starts saturating the CPU, a hard disk dies, a RAM chip gets fried, a meteor hits the Earth, etc.)
As others have said, it's not a good idea to just kill a thread, which is why the stop() method has been deprecated. It's just too easy to introduce deadlocks this way. There are other reasons why stopping a thread externally is bad, but I won't get into them here.
Status checks really are the only other way to go, but I can understand why you'd want to avoid them. Checks add overhead and make the code cumbersome if your run() method has many lines of code... but there's simply no other thread-safe way to stop a thread.
That said - there are four components of deadlock: mutual exclusion, hold and wait, non-pre-emption, and circular wait. If you can guarantee that any one of these conditions will never be met inside your run() method, then you will never encounter a deadlock by calling stop().
I am actually looking for an easier way to kill the thread not matter where the thread is running at. But most of the solutions in internet point me to use boolean flag to control the execution of the thread, if I want to stop the thread then set the boolean variable to false.
But what if the task that in the runnable is a LONG linear task, which mean the task is not repeating? In that case, it is not so easy to create a 'while' loop to cover the whole block of task.
It is really so temptative to use Thread.stop but the warning "Deprecated" seem like quite dangerous to use. I have read through this article
Why Are Thread.stop, Thread.suspend, Thread.resume and Runtime.runFinalizersOnExit Deprecated?
but I can't understand
If any of the objects previously protected by these monitors were in
an inconsistent state, other threads may now view these objects in an
inconsistent state. Such objects are said to be damaged.
What does the "inconsistent state" mean? I appreciate if anyone can explain about this.
I want to extend my question to a more lower level of view, let say i = i + 1; in JVM (perhaps assembly language alike), maybe this Java statement will be split into few smaller instructions, for example like move i ; add i ; get i into memory 0x0101 (This is an example! I totally don't know assembly language!)
Now, if we call thread.stop, where actually will it stop at? Will the thread stop after a COMPLETED Java statement, or could be in the middle of the "assemble language"? If the answer is the second, could it be reason that we said
Such objects are said to be damaged.
?
Ok, my question is kind of confused, hope someone can understand and explain. Thanks in advance.
"Damaged object" is a high-level concept, it doesn't happen at the JVM level. A programmer designs his class with thread safety in mind by guarding critical sections with locks. It is an invariant of his class that each critical section either runs in full, or doesn't run at all. When you stop a thread, a critical section may have been interrupted in the middle, so disrupting the invariant. At that moment the object is damaged.
Stopping a thread conceals many more dangers, like no cleanup performed, no acquired resources released, etc. If a thread doesn't give up what it is doing, there is no way to make it stop without compromising the entire application.
In practice, whenever one faces the need to run alien code that may need to be forcefully aborted, this must be done in a separate process because killing a process at least performs OS-level cleanup and does a much better job of containing the damage.
The "inconsistent state" means state of data as your application cares about, state that your application logic have carefully produced by making your application thread-safe with locks/monitors etc.
Imagine you have this simple method:
public synchronized void doSomething()
{
count++;
average = count/total;
}
This method, along with other methods are synchronized, as multiple threads are using this object.
Perhaps there's a
public synchronized AverageAndCount getMeasurement()
{
return new AverageAndCount(average, count);
}
This assures that a thread can't read an incomplete measurement, i.e. if the current measurement is in the process of being calculated inside e.g. doSomething(), getMeasurement() will block/wait until that's finished.
Now, imagine the doSomething is run in a thread, and you call .stop() on that thread.
So the thread might be stopped right after it performs count++;, the monitor that's held is unlocked and the method terminates and average = count/total; is not executed,
That means the data is now inconsistent. Anyone calling getMeasurement() afterwards will now get inconsistent data.
Note also that at this point it is not very relevant whether this happens at a java statement level, or at a lower level, the data can be in an inconsistent state that you can't reason about in any case.
I'm no expert but this is what I think.
If you use Thread.stop() you cause the ThreadDeath exception that will cause all monitors to be released.
Since you provoke an exception you are applying an unnatural behaviour to the state of things.
Other threads relying on those monitors could enter in an inconsistent situation because they were not expecting it. And I don't think you can even anticipate the monitors releasing order.
I believe the concern is that the thread may be in the middle of a synchronize block performing multi-step updates to an object's members. If the thread is stopped abruptly, then some updates will have occurred but not others and now the object's state may render it unusable.
I have my doubts that the ThreadDeath handling will release a Lock backed by the AbstractQueuedSynchronizer which could leave the application on the path to a sort of deadlock.
At any logical point in your long sequence of code you can simply add:
if (Thread.interrupted()) {
throw new InterruptedException();
}
...this will exit execution at this point if it is determined that Thread.interupt() was called on the Thread executing the long running task.
It's not clear way to stop the thread.actually deprecated the stop() method whenever run() method is completed or any exception is occurred then thread is stop.by using the boolean flag variable .Bydefault "false"
In my Java application with a Swing GUI, I would like to achieve the following.
There is a non-GUI thread running, performing some work. At one point, this thread needs input from the user before it can continue. Then, I would like to make some changes to the GUI, await a specific GUI action (like the user pressing the OK button), get the entered data from the GUI to the non-GUI thread, and let it continue with the computation.
Looking around, I have found a lot of information about how to initiate the execution of a (long running) task from the Swing GUI thread on another thread, but nothing on my problem.
SwingUtilites.invokeAndWait sounds like it does the job, but first, it takes a Runnable argument instead of a Callable, so there is no straightforward way to return a result, and second, it does not solve the problem of waiting for a certain GUI event.
I realize I could make up my own solution using e.g. a CountDownLatch, but to me, the problem seems frequent enough for there to be a standard solution.
So, my questions are: Is this really a frequent problem, and if yes, is there a solution in the standard library / libraries? If there is no standard solution, how would you solve it? If this problem doesn't occur often, why not?
Kicking off the GUI changes is easy, so I assume you're only asking about getting data back to the worker thread.
First, create a Blocking Queue. Have the worker thread call take() on the queue, and it will block. In GUI space, once the user enters valid input, put it on the queue with offer() and the worker thread will receive the data and can continue.
I think, you can use ExecutorService where you can also track progress of your task through Future interface.
java.awt.EventQueue.invokeLater works nicely for running code on the AWT EDT. Propbably best to copy mutable data or better use immutable data. Locks are possible, but a bit dicey.
If you other thread is an event dispatch loop, you could implement something like invokeLater for your thread (but don't make it static!). Probably use it behind some interface that makes sense to the behaviour of the thread - so it's real operations rather than run which is specified as doing anything it pleases. If your thread is going to block, then a BlockQueue is fine, but don't block from the AWT EDT.
java.awt.EventQueue.invokeAndWait is like using a lock. Probably you are going to use another lock. Or perhaps a lock like invokeAndWait on you own thread. If you don't, AWT uses a lock anyway. So, uncontrolled nested locks, that probably means deadlock. Don't use invokeAndWait!
final bool result = doSomething();
SwingUtilities.invokeLater( new Runnable(){
//Runnable method implementation.
//use result in your method like local var.
});
Make sure that your shared data is synchronized use lock objects.
If you need to pass arguments to Runnable just make your local variables final,
and use them in run method.
I am not understanding this concept in any manner.
public class SomeName {
public static void main(String args[]) {
}
}
This is my class SomeName. Now what is thread here.
Do we call the class as a thread.
Do we call this class as thread when some other object is trying to access its method or members?
Do we call this class as thread when some other object is trying to access this object?
What does it mean when we call something in java as thread-safe ?
Being thread-safe means avoiding several problems. The most common and probably the worst is called threadlock. The old analogy is the story of the dining philosophers. They are very polite and will never reach out their chopsticks to take food when someone else is doing the same. If they all reach out at the same time, then they all stop at the same time, and wait...and nothing ever happens, because they're all too polite to go first.
As someone else pointed out, if your app never creates additional threads, but merely runs from a main method, then there is only one thread, or one "dining philosopher," so threadlock can't occur. When you have multiple threads, the simplest way to avoid threadlock is to use a "monitor", which is just an object that's set aside. In effect, your methods have to obtain a "lock" on this monitor before accessing threads, so there are no collisions. However, you can still have threadlock, because there might be two objects trying to access two different threads, each with its own monitor. Object A has to wait for Object B to release its lock on monitor object 1; Object B has to wait for Object A to release its lock on monitor object 2. So now you're back to threadlock.
In short, thread safety is not terribly difficult to understand, but it does take time, practice and experience. The first time you write a multi-threaded app, you will run into threadlock. Then you will learn, and it soon becomes pretty intuitive. The biggest caveat is that you need to keep the multi-threaded parts of an app as simple as possible. If you have lots of threads, with lots of monitors and locks, it becomes exponentially more difficult to ensure that your dining philosophers never freeze.
The Java tutorial goes over threading extremely well; it was the only resource I ever needed.
You might want to think of thread as CPU executing the code that you wrote.
What is thread?
A thread is a single sequential flow of control within a program.
From Java concurrency in practice:
Thread-safe classes encapsulate any needed synchronization so that
clients need not provide their own.
At any time you have "execution points" where the JVM is running your code stepping through methods and doing what your program tells it to do.
For simple programs you only have one. For more complex programs you can have several, usually invoked with a new Thread().run or an Executor.
"Thread-safe" refers to that your code is written in such a way that one execution point cannot change what another execution point sees. This is usually very desirable as these changes can be very hard to debug, but as you only have one, there is not another so this does not apply.
Threads is an advanced subject which you will come back to later, but for now just think that if you do not do anything special with Threads or Swing this will not apply to you. It will later, but not now.
Well, in your specific example, when your program runs, it has just 1 thread.
The main thread.
A class is thread safe when an object of that class can be accessed in parallel from multiple threads (and hence from multiple CPUs) without any of the guarantees that it would provide in a single threaded way to be broken.
You should read first about what exactly threads are, for instance on Wikipedia, which might make it then easier to understand the relation between classes and threads and the notion of threadsafety.
Every piece of code in Java is executed on some thread. By default, there is a "main" thread that calls your main method. All code in your program executes on the main thread unless you create another thread and start it. Threads start when you explicitly call the Thread.start() method; they can also start implicitly when you call an API that indirectly calls Thread.start(). (API calls that start a thread are generally documented to do so.) When Thread.start() is called, it creates a new thread of execution and calls the Thread object's run() method. The thread exits when its run() method returns.
There are other ways to affect threads, but that's the basics. You can read more details in the Java concurrency tutorial.