17

Since I am writing a profiler focusing on concurrency aspects, I am looking for a good artificial example using synchronization mechanisms in Java. My profiler makes visible some actions related to threading; for instance:

  • calling notify/wait
  • thread changes its state
  • a thread is contended with another thread for a monitor lock
  • a monitor lock has been acquired by a thread after contending for it with another
  • measure the execution time of each method
  • which thread has accessed a certain method and how often
  • etc.

So what I am looking for, is a Java program which seems to be understood at first glance, but when executing it, you start to wonder about the results. I hope that my profiler might be able to detect what is going on in the background.


To clarify myself I give you an example, the book Java Concurrency in Practice by Brian Goetz gives "toxic" code examples which are used for learning reasons.

@NotThreadSafe
public class ListHelper<E> {
    public List<E> list =
        Collections.synchronizedList(new ArrayList<E>());
    ...
    public synchronized boolean putIfAbsent(E x) {
        boolean absent = !list.contains(x);
        if (absent)
            list.add(x);
        return absent;
    }
}

This is intended to be an extension of a thread-safe class, by the method putIfAbsent. Since list is synchronized, but putIfAbsent uses another lock for protecting the state as the methods defined on the list.

The profiler could display the used monitor locks and to the suprise of the user (or not...) the user would see there are two possible monitor locks instead of one.

I don't like this example very much, but I wouldn't ask, if I had already a bunch of good examples.


I found out my question is similar to this: What is the most frequent concurrency issue you've encountered in Java? and Java concurrency bug patterns.

But they refer only to broken concurrent programs. I am also looking for thread-safe implementations, but where it still not obvious that they are thread-safe.

Community
  • 1
  • 1
Konrad Reiche
  • 27,743
  • 15
  • 106
  • 143

7 Answers7

11

Have a look at the list of FindBugs bug descriptions, specifically those belonging to category of Multithreaded correctness (right table column).

Each of these bugs contain references on why a particular idiom is bad and how can it be solved.

mindas
  • 26,463
  • 15
  • 97
  • 154
  • This is a very nice list, thanks for the advice. Although most of it is not very applicable in means of a profiler, they will definietly serve a purpose. And maybe I will start displaying warnings when a monitor lock is of instance Boolean! Thanks a lot! – Konrad Reiche Jul 03 '11 at 14:48
3

I'd go back in time, like maybe seven years or more, and find some open source code from the era before java.util.concurrent. Just about anything that rolled its own concurrency is going to have some subtle bugs in it, 'cause concurrency is hard to get right.

Ross Judson
  • 1,132
  • 5
  • 11
3

How about this?

class ObjectReference {

  private volatile Object obj = null;      

  public void set(Object obj) {
    if (obj == null) {
      throw new IllegalArgumentException();
    }
    this.obj = obj;
    synchronized (this) {
      notifyAll();
    }
  }

  /**
   * This method never returns null
   */
  public Object waitAndGet() {
    if (obj != null) {
      return obj;
    }
    synchronized (this) {
      wait();
      return obj;
    }
  }
}

You could get null from waitAndGet() actually. See — Do spurious wakeups actually happen?

Community
  • 1
  • 1
Denis Bazhenov
  • 9,680
  • 8
  • 43
  • 65
  • This looks interesting, it's perfect for my profiling mechanism, thanks a lot, also for the linked question. What I could need is a concept to enforce a spurious wake-up. – Konrad Reiche Jul 06 '11 at 08:06
  • 1
    The code has a race condition. If the "set" method would run in full between "if" and "synchronized" of the waitAndGet method, then the latter method will be waiting forever. The "test and test-and-set" idiom should be used instead. – kan Aug 01 '11 at 13:53
  • @kan: you are correct. LockSupport.park/unpark are another way to address this. e.g. if unpark() in set() is called by Ts while Tw has not yet hit synchronized, park() will return immediately. – alphazero Aug 02 '11 at 18:39
2

Dining philosophers problem is a classical concurrency example. This link has one possible solution and more can be found around the web.

As described in the first link this example illustrates quite many of the common concurrency problems. Please let your profiler show how many it can track!

mico
  • 12,730
  • 12
  • 59
  • 99
2

See the The Java Specialists' Newsletter for a consistent stream of small Java puzzles, many of which should fit your testing needs.

pyroscope
  • 4,120
  • 1
  • 18
  • 13
1

I would recommend looking around (or asking the authors) for the IBM ConTest benchmark suite as it contains a number of Java concurrency bugs (unfortunately not large open-source programs). The good thing about this benchmark is that the bugs are already documented (type, and location).

If you want to find more programs I would recommend taking a look at some of the research papers in the area of software testing/quality of concurrent programs. They should indicate the sample programs they've used in their studies.

If all else fails you could try search on GitHub (or similar service) for repositories that contain the necessary concurrency mechanisms (i.e., synchronization). You might find a large amount of Java code that way, the only problem is that the bugs are not documented (unless you look for commit fixes).

I think these three suggestions will supply you with enough programs to test your concurrency profiler.

Kevin Jalbert
  • 3,115
  • 3
  • 26
  • 39
0

Maybe Eclipse or a Tomcat deployment? Neither one is very artificial, but I could imagine wanting good tools while debugging one or the other.

sarnold
  • 102,305
  • 22
  • 181
  • 238
  • 2
    @sarnold, tomcat is pretty simple if it comes to concurrency, it has quite a bit of dataraces, though. However, the overall contention points are few. Eclipse is anything but highly concurrent either, GUIs are not amongst the concurrent type of programs. – bestsss Jun 12 '11 at 23:28
  • @bestsss I do not agree for saying GUI are not "concurrent". Typically drawing, event handling is done on one thread that shall never block. And heavy computation are done in background threads (in eclipse a good example is compilation, but all treatment are done in background like downloading eclipse updates, validating files, updating your code from your VCS, controlling running applications/tests) – Nicolas Bousquet Jul 01 '11 at 08:09
  • @Nicolas, that's not concurrent, having few tasks executed simultaneously w/o any synchronization/collision point is an uninteresting case. And downloading doesn't even need a separate thread if you use non-blocking IO. That's just not an example of "a surprising concurrent" program. GUIs may field massive computations but usually the process doesn't affect the GUI, having a progress bar or the via simple messaging is nothing special. – bestsss Jul 01 '11 at 08:40
  • If you think about eclipse (or about any moderately complex UI) carefully and how it is used this is not exactly as simple as it appear. First even if there is only a few dozen concurrent thread, there are still there. And making UI unresponsive or worse subject to deadlock is a real problem. – Nicolas Bousquet Jul 01 '11 at 14:16
  • In fact if your software has lot of synchronization problems this is a design problem. Web server share nothing architecture is an example. Many (maybe hundreds) concurrent requests, but no shared state. Scala & Clojure are using immutable objects and actor or transactionnal memory. Even at JDK lvl, java 5 provide executors, a great way to abstract task execution at a higher level. Non blocking IO, nobody use it now plus it make "spagetti code" don't scale to multi core or long running tasks. – Nicolas Bousquet Jul 01 '11 at 14:28
  • @Nicolas, just because most developers know the whole point is to _reduce_ sharing among threads doesn't mean _every_ developer knows -- and there are giant piles of legacy code (I'm sure even in Java) that were written with less-than-ideal designs. GUI seems like a ripe source of concurrent bugs to me, since the interface is often in another thread from other work, and I can imagine the interface between them being done haphazardly or make assumptions that No User Can Click Buttons That Fast. I am hoping platzhirsch responds with findings. :) – sarnold Jul 01 '11 at 23:09