(1) Thread.dumpStack(), not Thread.dumpStackTrace(), not Thread.currentThread().dumpStack().

(2) thread can sleep with or without acquiring a lock, inside or outside synchronized block. When sleeping without a lock, the CPU resource is re-allocated to one of the ready-to-run threads. When sleeping inside synchronized block with a monitor lock, the lock is not relinquished, and the CPU is re-allocated to one of the other runnable threads that are not waiting on this lock.

(3) wait-notify-flag pattern. wait is almost always inside a while(flag) loop. There can be multiple threads waiting on the same monitor, some is waiting for the flag to change value, and others are not. In other words, there could be homogeneous threads and/or heterogeneous waiters. Once the flag changes value and notifyAll() is invoked, all threads waiting on the same monitor will be awaken. All of them exit waiting state and enter ready-to-run state, but only one of them will get the lock and proceed. If the lucky one consumes (reset) the flag after obtaining the lock, the previous flag set in notifyAll() becomes obsolete. Therefore, other threads, after they get the monitor, will need to recheck the flag to decide to wait again or proceed.

Another reason wait is inside a loop is there can be spurious wakeup, which are not triggered by notify or notifyAll calls. wait can also be interrupted by other threads. So the wait-notify protocol is not 100% reliable, and that's why a flag is needed to aid the inter-thread communication.

When to use notify and when to use notifyAll? When all waiters are homogeneous, i.e., whoever gets the monitor doesn't matter, use notify. When waiters are heterogeneous, use notifyAll to ensure the correct threads are awaken. If waiter are heterogeneous and we call notify, a waiter that does not care about the flag may be picked to proceed, while those waiters interested in the flag will not get the signal.

The flag should be exclusively for this purpose, not used by other part of the application. All access to this flag is inside synchronized block, so no need to make it volatile or AtomicBoolean.

(4) make the lock object final if possible, for example:
private final Object lock = new Object();
Do not synchronize on string literals, which are merely reference to the same string object in the string pool, or global constants. It will unintentionally cause too many threads competing for the same lock.

(5) volatile can be used on fields of primitive type, primitive wrapper types, or any other Object types. A typical use is in singleton DCL pattern. If a mutable field is simply read or written by multiple threads, then making it volatile usually suffice. One step up in concurrency is to use java.util.concurrent.atomic.* classes like AtomicInteger, AtomicBoolean, etc. Atomic types are ideal for simple compound operations like read-update-assignment, or if-absent-set. Anything more complicated than that will need synchronized access.

Further readings:
Sun's Java Concurrency Tutorial

stackoverflow discussion on wait, notify, CountdownLatch, etc

(6), 3 ways to get a new thread:
* extend java.lang.Thread class and overriding its run() method;

* provide an impl of Runnable interface and use it to instantiate a new thread;

* provide an impl of Runnable interface and call ThreadFactory.newThread(runnable). Get the default ThreadFactory with Executors.defaultThreadFactory().

See their differences in another post: Extend Thread vs implement Runnable
0

Add a comment

When writing javadocs, IntelliJ automatically adds a closing tag for html elements. For instance, after typing <lt>, it automaticaly adds </lt>, or after typing <p>, it adds </p>. It can be annoying since simple html elements like those used in javadocs don't really need ending tags.
To disable javadoc automatic closing tags in IntelliJ, simply go to IntelliJ Preferences -> Editor -> Smart Keys, then on the right panel, uncheck Automatically insert closing tag.

Intellij 14 screenshot:


 Intellij 15 screenshot:

A related note, JDK 8 has tightened javadoc syntax check, and as a result self-closing elements like <p/>, or <br/> are deemed invalid and will cause failures. See JDK-8020619. However, this checking can be disabled by passing nonstandard option -Xdoclint:none to javadoc tool. For official javadoc guidelines, see How to Write Doc Comments for the Javadoc Tool .
0

Add a comment

Labels
Archive
Popular Posts
Popular Posts
  • Two JVM options are often used to tune JVM heap size: -Xmx for maximum heap size, and -Xms for initial heap size. Here are some common mi...
  • Simple enum . The ; after the last element is optional, when this is the end of enum definition. public enum Color { WHITE, BLACK, RED, ...
  • How to set project classpath in Eclipse and NetBeans are similar: just right-click the project name, choose Properties to bring up the Prope...
  • Let's say I need to spawn multiple threads to do the work, and continue to the next step only after all of them complete. I will need t...
  • This is a sample web.xml based on Servlet 2.5 (part of Java EE 5) that declares common elements. All top-level elements are optional, and c...
  • The default string value for java enum is its face value, or the element name. However, you can customize the string value by overriding toS...
  • Prior to JDK 6, we can check if a string is empty in 2 ways: if(s != null && s.length() == 0) if(("").equals(s)) Checking ...
  • When writing javadocs, IntelliJ automatically adds a closing tag for html elements. For instance, after typing <lt>, it automaticaly a...
  • StringBuilder was introduced in JDK 1.5. What's the difference between StringBuilder and StringBuffer? According to javadoc , StringBu...
  • With array, we can easily declare and initialize it at the same time: String[] favorites = new String[] {"EJB", "JPA", ...
Loading