You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
When we use the submit() method we return a future object. If we use the get() method, there is a chance that the program will halt!
We can get around this by using an overloaded version of get()!
We can determine whether the task which has been submitted is actually complete with the following methods:
booleanisDone();
booleanisCancelled();
booleancancel(); // attempts to cancel the taskVget(); // retrieves result of task, waiting endlessly if not yet availableVget(longmillis, TimeUnitunit); // retrieves result in alotted time, otherwise throws TimeoutException
Future<?> f3 = scheduledService.scheduleAtFixedRate(r, 1, 1, TimeUnit.SECONDS);
// this will print hello exactly every second Future<?> f4 = scheduledService.scheduleWithFixedDelay(r, 0, 1, TimeUnit.SECONDS);
// this will print hello exactly 1 second after the previous hello is printed
🟥 7.3 Synchronizing Data Access
🟡 Atomic Classes
We have the following Atomic classes in the Concurrency API:
AtomicBoolean
AtomicInteger
AtomicLong
AtomicReference
AtomicIntegerArray
AtomicLongArray
AtomicReferenceArray
Here are common methods for these classes:
get();
set();
getAndSet(newValue); // gets old value while setting new valueincrementAndGet(); // increments and returns the incremented valuegetAndIncrement(); // gets old value and increments afterdecrementAndGet(); // decrements and returns decremented valuegetAndDecrement(); // gets old value and decrements after
Here is an example of using an Atomic class to ensure a counter is kept THREAD-SAFE and to prevent race conditions:
If we used new ConcurrentHashMap<>() instead, we would not have this problem!💡
🟡 Blocking Queues
The LinkedlockingDeque and LinkedBlockingQueue implement the BlockingQueue and BlockingDeque interfaces
BlockingQueue waiting methods:
booleanoffer(Ee, longtimeout, TimeUnitunit);
// adds item to queue in alotted time if space is availableEpoll(longtimeout, TimeUnitunit);
// retrieves and removes an item from the queue in alotted time if available
These methods can throw an InterruptedException as they can be interrupted before finishing:
booleanofferFirst(Ee, longtimeout, TimeUnitunit);
// adds item to front of queuebooleanofferLast(Ee, longtimeout, TimeUnitunit);
// adds item to back of queueEpollFirst(longtimeout, TimeUnitunit);
// retrieves and removes element at front of queueEpollLast(longtimeout, TimeUnitunit);
// retrieves and removes element at back of queue
Again, InterruptedException must be caught and handled!
🟡 SkipList Collections
The ConcurrentSkipListMap and ConcurrentSkipListSet are concurrent versions of TreeMap and TreeSet
These
🟡 CopyOnWrite Collections
The CopyOnWriteArrayList and CopyOnWriteSet are concurrent versions of Lists and Sets.
These classes let us add/remove elements in a for loop, the iterator takes a snapshot of the elements and loops over these elements during each iteration
With parallel streams, behaviour can not be defined:
Arrays.asList(1,2,3,4,5,6).stream().findAny(); // will ALWAYS be 1Arrays.asList(1,2,3,4,5,6).parallelStream().findAny(); // unable to predict the result
[start=0,middle=5,end=10]
[start=5,middle=7,end=10]
BASE CASE FROM: 7, TO: 10
[start=0,middle=2,end=5]
BASE CASE FROM: 5, TO: 7
BASE CASE FROM: 2, TO: 5
BASE CASE FROM: 0, TO: 2
Animal: 7 weighed 0.0
Animal: 8 weighed 40.0
Animal: 9 weighed 29.0
Animal: 2 weighed 69.0
Animal: 3 weighed 83.0
Animal: 5 weighed 71.0
Animal: 0 weighed 55.0
Animal: 1 weighed 45.0
Animal: 6 weighed 49.0
Animal: 4 weighed 87.0
Sum: 528.0
If the .join() method were to be called directly after fork, the application would generate single-threader performance:
intmiddle = start+((start-end)/2);
System.out.println("[start="+start+",middle="+middle+",end="+end+"]");
RecursiveTask<Double> otherTask = newWeighAnimalTask(weights,start,middle);
otherTask.fork().join(); // DO NOT DO!!!!returnnewWeighAnimalTask(weights,middle,end).compute()+otherTask;
🟥 7.7 Identifying Threading Problems
Liveliness is the property of an application not encountering unexpected delays
Deadlock is when a resource is blocked from being used from a thread
Starvation occurs when a thread is perpetually denied access to a shared resouce as a result of other threads constantly taking the resource
Livelock occurs when two or more threads are blocked forever but appear active. This is often the result of two threads trying to attempt to resolve a deadlock
Race conditions are when two or more threads try to complete a related task at the same time. It is the undesirablee result which occurs when two tasks which should be done sequentially are done at the same time