I'm wondering what good ways there would be make assertions about synchronization or something so that I could detect synchronization violations (while testing).
That would be used for example for the case that I'd have a class that is not thread-safe and that isn't going to be thread-safe. With some way I would have some assertion that would inform me (log or something) if some method(s) of it was called from multiple threads.
I'm longing for something similar that could be made for AWT dispatch thread with the following:
public static void checkDispatchThread() {
if(!SwingUtilities.isEventDispatchThread()) {
throw new RuntimeException("GUI change made outside AWT dispatch thread");
}
}
I'd only want something more general. The problem description isn't so clear but I hope somebody has some good approaches =)
You are looking for the holy grail, I think. AFAIK it doesn't exist, and Java is not a language that allows such an approach to be easily created.
"Java Concurrency in Practice" has a section on testing for threading problems. It draws special attention to how hard it is to do.
When an issue arises over threads in Java it is usually related to deadlock detection, more than just monitoring what Threads are accessing a synchronized section at the same time. JMX extension, added to JRE since 1.5, can help you detect those deadlocks. In fact we use JMX inside our own software to automatically detect deadlocks an trace where it was found.
Here is an example about how to use it.
IntelliJ IDEA has a lot of useful concurrency inspections. For example, it warns you when you are accessing the same object from both synchronised and unsynchronised contexts, when you are synchronising on non-final objects and more.
Likewise, FindBugs has many similar checks.
As well as #Fernando's mention of thread deadlocking, another problem with multiple threads is concurrent modifications and the problems it can cause.
One thing that Java does internally is that a collection class keeps a count of how many times it's been updated. And then an iterator checks that value on every .next() against what it was when the interator was created to see if the collection has been updated while you were iterating. I think that principle could be used more generally.
Try ConTest or Covertity
Both tools analyze the code to figure out which parts of the data might be shared between threads and then they instrument the code (add extra bytecode to the compiled classes) to check if it breaks when two threads try to change some data at the same time. The two threads are then run over and over again, each time starting them with a slightly different time offset to get many possible combinations of access patterns.
Also, check this question: Unit testing a multithreaded application?
You might be interested in an approach Peter Veentjer blogged about, which he calls The Concurrency Detector. I don't believe he has open-sourced this yet, but as he describes it the basic idea is to use AOP to instrument code that you're interested in profiling, and record which thread has touched which field. After that it's a matter of manually or automatically parsing the generated logs.
If you can identify thread unsafe classes, static analysis might be able to tell you whether they ever "escape" to become visible to multiple threads. Normally, programmers do this in their heads, but obviously they are prone to mistakes in this regard. A tool should be able to use a similar approach.
That said, from the use case you describe, it sounds like something as simple as remembering a thread and doing assertions on it might suffice for your needs.
class Foo {
private final Thread owner = Thread.currentThread();
void x() {
assert Thread.currentThread() == owner;
/* Implement method. */
}
}
The owner reference is still populated even when assertions are disabled, so it's not entirely "free". I also wouldn't want to clutter many of my classes with this boilerplate.
The Thread.holdsLock(Object) method may also be useful to you.
For the specific example you give, SwingLabs has some helper code to detect event thread violations and hangs. https://swinghelper.dev.java.net/
A while back, I worked with the JProbe java profiling tools. One of their tools (threadalyzer?) looked for thread sync violations. Looking at their web page, I don't see a tool by that name or quite what I remember. But you might want to take a look. http://www.quest.com/jprobe/performance-home.aspx
You can use Netbeans profiler or JConsole to check the threads status in depth
Related
I am coding as part of a project which uses multithreading and I'm trying to find ways to detect thread mistakes in my code.
Are there some existing tools I could use to help me do this?
For example-
an assert that my method is being called by the correct thread
or
some kind of static checking with annotations, similar to #Nullable and #NotNull, to detect when my code calls a method from the wrong thread.
Although the project is multithreaded, there is almost no synchronisation required because the different threads don't access the same objects, they have their own instances.
Broadly speaking, there are four threads running at once
Server thread = maintains the state of the game for one or more
clients
Client thread = processes user input, maintains a local
copy/cache of server data for rendering
NetworkMessage thread = processes incoming/outgoing messages
between server and client
Render thread = processes the local data into rendering information for the
graphics card
The classes are sometimes intended for only one of the threads (for example user input polling is client-only), sometimes they are for multiple threads (eg the calculated movement of a projectile uses the same code on both client and server simultaneously to reduce perceived lag). Several times I've called a method from the wrong thread, leading to subtle and unrepeatable bugs and very nearly serious monitor screen damage (from my fist)
What I have thought of so far is something like this:
public void myMethodThatAssumesClientThreadOnly() {
assert checkThread(CLIENT);
// can now happily call other client-thread code without fear
}
but I would prefer something with static checking similar to #Nullable
eg
#Thread(CLIENT)
void myClientMethod() {
//client-only stuff here
}
#Thread(SERVER)
void myServerMethod() {
//server-only stuff here
}
#Thread(CLIENT + SERVER)
void myClientAndMethod() {
myClientMethod(); // error- server thread might call client method
}
Unfortunately, being an annotation noob, I have no clue whether this is easy or actually very hard.
Any pointers? I can't imagine I'm the first one to look for something like this.
TGG
The Checker Framework enables the creation of compile-time static checkers that verify program correctness. Its GUI Effect Checker is similar to what you want. Here is an abridged excerpt from its manual:
One of the most prevalent GUI-related bugs is invalid UI update or invalid thread access: accessing the UI directly from a background thread.
If a background thread accesses a UI element such as a JPanel (by calling a JPanel method or reading/writing a field of JPanel), the GUI framework raises an exception that terminates the program.
It is difficult for a programmer to remember which methods may be called on which thread(s). The GUI Effect Checker solves this problem. The programmer annotates each method to indicate whether:
It accesses no UI elements (and may run on any thread).
It may access UI elements (and must run on the UI thread).
The GUI Effect Checker statically enforces that UI methods are only called from the correct thread.
The GUI Effect Checker is tuned to detect and prevent GUI threading errors, whereas you are concerned about client-server threading errors. However, the principles are the same and you should be able to adapt the GUI Effect Checker to your needs with relatively few changes.
There is a paper that discusses case studies using the GUI Effect Checker.
An alternative is to adapt a bug finder for finding errors in multithreaded applications. Unlike the GUI Effect Checker, it does not give a guarantee that there are no threading bugs. However, it is effective in practice, and it does not require you to write any annotations in your program.
Finally, the Checker Framework also contains a Lock Checker that ensures correct synchronization. That helps to prevent concurrency errors, though it's orthogonal to your chief concerns about thread safety.
This will assert that method foobar() is called by the correct thread...
SomeType foobar(...) {
assert(Thread.currentThread() == theCorrectThread);
...
}
...If, somewhere in your code prior to the first foobar() call you have set
Thread theCorrectThread = new Thread(...);
but I would prefer something with static checking similar to #Nullable
I know very little about annotations myself. I know that they can be used to attach meta-information to compiled classes, and I know that the program can obtain that information at run-time by calling methods of the Class object, but if there's any way an annotation can define compile-time behavior, that's beyond my ken.
Probably a moot point anyway. When the compiler is processing a .java file, there is no way for it to tell what thread or threads might possibly execute the code that it contains.
Can anyone please explain to me the consequences of mutating a collection in java that is not thread-safe and is being used by multiple threads?
The results are undefined and somewhat random.
With JDK collections that are designed to fail fast, you might receive a ConcurrentModificationException. This is really the only consequence that is specific to thread safety with collections, as opposed to any other class.
Problems that occur generally with thread-unsafe classes may occur:
The internal state of the collection might be corrupted.
The mutation may appear to be successful, but the changes may not, in fact, be visible to other threads at any given time. They might be invisible at first and become visible later.
The changes might actually be successful under light load, but fail randomly under heavy load with lots of threads in contention.
Race conditions might occur, as was mentioned in a comment above.
There are lots of other possibilities, none of them pleasant. Worst of all, these things tend to most commonly reveal themselves in production, when the system is stressed.
In short, you probably don't want to do that.
The most common outcome is it looks like it works, but doesn't work all the time.
This can mean you have a problem which
works on one machine but doesn't on another.
works for a while but something apparently unrelated changes and your program breaks.
whenever you have a bug you don't know if it's a multi-threading issue or not if you are not using thread safe data structures.
What can happen is;
you rarely/randomly get an error and strange behaviour
your code goes into an infinite loop and stops working (HashMap used to do this)
The only option is to;
limit the amount of state which is shared between threads, ideally none at all.
be very careful about how data is updated.
don't rely on unit tests, you have to understand what the code doing and be confident it will be behave correctly in all possible situations.
The invariants of the data structure will not be guaranteed.
For example:
If thread 2 does a read whilst thread 1 is adding to the DS thread 1 may consider this element added while thread 2 doesn't see that the element has been added yet.
There are plenty of data structures that aren't thread-safe that will still appear to function(i.e. not throw) in a multi threaded environment and they might even perform correctly under certain circumstances(like if you aren't doing any writes to the data structure).
To fully understand this topic exploring the different classes of bugs that occur in concurrent systems is recommended: this short document seems like a good start.
http://pages.cs.wisc.edu/~remzi/OSTEP/threads-bugs.pdf
I've been caught by yet another deadlock in our Java application and started thinking about how to detect potential deadlocks in the future. I had an idea of how to do this, but it seems almost too simple.
I'd like to hear people's views on it.
I plan to run our application for several hours in our test environment, using a typical data set.
I think it would be possible to perform bytecode manipulation on our application such that, whenever it takes a lock (e.g. entering a synchronized block), details of the lock are added to a ThreadLocal list.
I could write an algorithm that, at some later point, compares the lists for all threads and checks if any contain the same pair of locks in opposite order - this would be reported as a deadlock possibility. Again, I would use bytecode manipulation to add this periodic check to my application.
So my question is this: is this idea (a) original and (b) viable?
This is something that we talked about when I took a course in concurrency. I'm not sure if your implementation is original, but the concept of analysis to determine potential deadlock is not unique. There are dynamic analysis tools for Java, such as JCarder. There is also research into some analysis that can be done statically.
Admittedly, it's been a couple of years since I've looked around. I don't think JCarder was the specific tool we talked about (at least, the name doesn't sound familiar, but I couldn't find anything else). But the point is that analysis to detect deadlock isn't an original concept, and I'd start by looking at research that has produced usable tools as a starting point - I would suspect that the algorithms, if not the implementation, are generally available.
I have done something similar to this with Lock by supplying my own implementation.
These days I use the actor model, so there is little need to lock the data (as I have almost no shared mutable data)
In case you didn't know, you can use the Java MX bean to detect deadlocked threads programmatically. This doesn't help you in testing but it will help you at least better detect and recover in production.
ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
long[] deadLockedThreadIds = threadMxBean.findMonitorDeadlockedThreads();
// log the condition or even interrupt threads if necessary
...
That way you can find some deadlocks, but never prove their absence. I'd better develop static checking tool, a kind of bytecode analizer, feeded with annotations for each synchronized method. Annotations should show the place of the annotated method in the resource graph. The task is then to find loops in the graph. Each loop means deadlock.
I know that thread safety of java sockets has been discussed in several threads here on stackoverflow, but I haven't been able to find a clear answer to this question - Is it, in practice, safe to have multiple threads concurrently write to the same SocketOutputStream, or is there a risk that the data sent from one thread gets mixed up with the data from another tread? (For example the receiver on the other end first receives the first half of one thread's message and then some data from another thread's message and then the rest of the first thread's message)
The reason I said "in practice" is that I know the Socket class isn't documented as thread-safe, but if it actually is safe in current implementations, then that's good enough for me. The specific implementation I'm most curious about is Hotspot running on Linux.
When looking at the Java layer of hotspot's implementation, more specifically the implementation of socketWrite() in SocketOutputStream, it looks like it should be thread safe as long as the native implementation of socketWrite0() is safe. However, when looking at the implemention of that method (j2se/src/solaris/native/java/net/SocketOutputStream.c), it seems to split the data to be sent into chunks of 64 or 128kb (depending on whether it's a 64bit JVM) and then sends the chunks in seperate writes.
So - to me, it looks like sending more than 64kb from different threads is not safe, but if it's less than 64kb it should be safe... but I could very well be missing something important here. Has anyone else here looked at this and come to a different conclusion?
I think it's a really bad idea to so heavily depend on the implementation details of something that can change beyond your control. If you do something like this you will have to very carefully control the versions of everything you use to make sure it's what you expect, and that's very difficult to do. And you will also have to have a very robust test suite to verify that the multithreaded operatio functions correctly since you are depending on code inspection and rumors from randoms on StackOverflow for your solution.
Why can't you just wrap the SocketOutputStream into another passthrough OutputStream and then add the necessary synchronization at that level? It's much safer to do it that way and you are far less likely to have unexpected problems down the road.
According to this documentation http://www.docjar.com/docs/api/java/net/SocketOutputStream.html, the class does not claim to be thread safe, and thus assume it is not. It inherits from FileOutputStream, which normally file I/O is not inherently thread safe.
My advice is that if the class is related to hardware or communications, it is not thread safe or "blocking". The reason is thread safe operations consume more time, which you may not like. My background is not in Java but other libraries are similar in philosophy.
I notice you tested the class extensively, but you may test it all day for many days, and it may not prove anything, my 2-cents.
Good luck & have fun with it.
Tommy Kwee
All,
What should be the approach to writing a thread safe program. Given a problem statement, my perspective is:
1 > Start of with writing the code for a single threaded environment.
2 > Underline the fields which would need atomicity and replace with possible concurrent classes
3 > Underline the critical section and enclose them in synchronized
4 > Perform test for deadlocks
Does anyone have any suggestions on the other approaches or improvements to my approach. So far, I can see myself enclosing most of the code in synchronized blocks and I am sure this is not correct.
Programming in Java
Writing correct multi-threaded code is hard, and there is not a magic formula or set of steps that will get you there. But, there are some guidelines you can follow.
Personally I wouldn't start with writing code for a single threaded environment and then converting it to multi-threaded. Good multi-threaded code is designed with multi-threading in mind from the start. Atomicity of fields is just one element of concurrent code.
You should decide on what areas of the code need to be multi-threaded (in a multi-threaded app, typically not everything needs to be threadsafe). Then you need to design how those sections will be threadsafe. Methods of making one area of the code threadsafe may be different than making other areas different. For example, understanding whether there will be a high volume of reading vs writing is important and might affect the types of locks you use to protect the data.
Immutability is also a key element of threadsafe code. When elements are immutable (i.e. cannot be changed), you don't need to worry about multiple threads modifying them since they cannot be changed. This can greatly simplify thread safety issues and allow you to focus on where you will have multiple data readers and writers.
Understanding details of concurrency in Java (and details of the Java memory model) is very important. If you're not already familiar with these concepts, I recommend reading Java Concurrency In Practice http://www.javaconcurrencyinpractice.com/.
You should use final and immutable fields wherever possible, any other data that you want to change add inside:
synchronized (this) {
// update
}
And remember, sometimes stuff brakes, and if that happens, you don't want to prolong the program execution by taking every possible way to counter it - instead "fail fast".
As you have asked about "thread-safety" and not concurrent performance, then your approach is essentially sound. However, a thread-safe program that uses synchronisation probably does not scale much in a multi cpu environment with any level of contention on your structure/program.
Personally I like to try and identify the highest level state changes and try and think about how to make them atomic, and have the state changes move from one immutable state to another – copy-on-write if you like. Then the actual write can be either a compare-and-set operation on an atomic variable or a synchronised update or whatever strategy works/performs best (as long as it safely publishes the new state).
This can be a bit difficult to structure if your new state is quite different (requires updates to several fields for instance), but I have seen it very successfully solve concurrent performance issues with synchronised access.
Buy and read Brian Goetz's "Java Concurrency in Practice".
Any variables (memory) accessible by multiple threads potentially at the same time, need to be protected by a synchronisation mechanism.