The document discusses concepts related to concurrent and parallel programming with threads in Java. It covers key topics such as concurrent programming using threads, challenges with shared mutable state and data visibility across threads, and improvements in Java like the ConcurrentHashMap that provide better concurrency support. It emphasizes that achieving parallelism requires minimizing shared mutable state and synchronization through techniques like immutable objects and data-oriented design.
1 of 17
More Related Content
Threads and concurrency in Java 1.5
1.
2. Notes on Concurrent, parallel programming with threads Concurrent = work done in several computational processes, only requires one CPU Parallel = work (computations) done simultaneous, requires multiple CPU:s – locally or distributed
3. GC and Threads and Java CG made easy in Java Person p = null; Concurrent programming made possible (but not easy) Low level support: threads and mutexes volatile boolean stop = false; public void stop() { stop = true; } public void run() { while(!stop) { try { // Do some work Thread.sleep(10); // check stop }catch(InterruptedException ie) { // Ignore } } } // stop = true; thread.interrupt();
4. Some Hard stuff Data visibility between threads Volitile semantics Asynchronous code Race conditions and Deadlocks Congestion/Performance
5. Data visibility Data not guaranteed to be visable between threads without synchronization long and double not even guaranteed to be ”complete” // In thread 1 at time 1 commonObject.myLong = Long.MAX_VALUE; // In thread 2 at time 2 if(commonObject.myLong > Integer.MAX_VALUE) {
6. Broken objects The ordering of access to a reference and a constructed object is not guaranteed
7. If one thread can see an object another thread constructs it might see broken objects (ref available before object constructed)
8. Double locking // Broken multithreaded version // "Double-Checked Locking" idiom class Foo { private Helper helper = null; public Helper getHelper() { if (helper == null) synchronized(this) { if (helper == null) helper = new Helper(); } return helper; } // other functions and members... }
9. Volitile behaviour up until Java 1.4 The Java memory model did not guarantee non reordering on Volatile before 1.5 class VolatileExample { int x = 0; volatile boolean v = false; public void writer() { // Before 1.5 could be done in any order x = 42; v = true; } public void reader() { if (v == true) { //uses x - guaranteed to see 42. } } } // Works with acquire/release semantics for volatile // Broken under current semantics for volatile class Foo { private volatile Helper helper = null; public Helper getHelper() { if (helper == null) { synchronized(this) { if (helper == null) helper = new Helper(); } } return helper; } } Broken up until 1.5 The order of x and v not guaranteed in 1.4
10. Sending asynchronous messages is complex public void fetchAsync() { Thread t = new Thread(new Runnable() { public void run() { // Do work in other thread dataArived("hello"); } }); t.start(); } public synchronized void dataArived(String s) { // Update data, must be synchronized somehow to be visable }
11. Reading and writing common data always requires synchronization Sets a limit to scalability
13. where P is percentage parallelizable work gives the maximum number of CPU:s that are meaningfull to use when speed is considered.
14. For example, of 5 percent of the application is serialized because of a common synchronization (such as read on a cache), the maximum number of CPU:s are 20
15. To fully gain througout by 64 cores about 99 % must be parallelizable
22. Atomic check and take action methods V putIfAbsent(K key, V value); boolean remove(Object key, Object value); V replace(K key, V value); boolean replace(K key, V oldValue, V newValue);
26. Uses Future and Callable Callable<String> worker = new Callable<String>() { int c = 0; public String call() { try {Thread.sleep(2000L);}catch(Exception ignore){} return "jobb no " + c++; } }; ExecutorService exe = Executors.newSingleThreadExecutor(); Future<String> result = exe.submit(worker); while(!result.isDone()) { // Do something other } String s = result.get();
32. Non blocking counting AtomicLong at = new AtomicLong(); // one thread, no synchronzied long current = at.get(); // another thread increment, no sync at.incrementAndGet();
33. To really solve the parallelity problem you have to look at the world differently Value (immutable)