| Line 3: |
Line 3: |
| | ===With apt=== | | ===With apt=== |
| | <nowiki>sudo apt-add-repository ppa:webupd8team/java | | <nowiki>sudo apt-add-repository ppa:webupd8team/java |
| − | sudo apt-get update
| + | sudo apt-get update |
| − | sudo apt-get install oracle-java8-installer</nowiki>
| + | sudo apt-get install oracle-java8-installer</nowiki> |
| | | | |
| | Also ensure your JAVA_HOME variable has been set to: | | Also ensure your JAVA_HOME variable has been set to: |
| Line 1,270: |
Line 1,270: |
| | executorService.shutdown(); | | executorService.shutdown(); |
| | } | | } |
| | + | } |
| | + | </syntaxhighlight> |
| | + | |
| | + | == Concurrency == |
| | + | |
| | + | === syncrhronized === |
| | + | If there are multiple synchronized methods on an instance only one of them can be run by threads at one point in time<syntaxhighlight lang="java"> |
| | + | public class Counter { |
| | + | private int i = 0; |
| | + | |
| | + | synchronized public void increment() { // synchronized keyword: only one thread can run at same time |
| | + | i++; // get; increment; set (Not atomic, not thread safe if not synchronized) |
| | + | } |
| | + | public int getI(){ |
| | + | return i; |
| | + | } |
| | + | } |
| | + | </syntaxhighlight> |
| | + | |
| | + | === Locks === |
| | + | Solve the multiple synchronized methods on same instance (apart from ReentrantLock thre are TryLock and TryForLock)<syntaxhighlight lang="java"> |
| | + | import java.util.concurrent.locks.ReentrantLock; |
| | + | |
| | + | public class BiCounterWithLock { |
| | + | private int i = 0; |
| | + | private int j = 0; |
| | + | Lock lockForI = new ReentrantLock(); |
| | + | Lock lockForJ = new ReentrantLock(); |
| | + | |
| | + | public void incrementI() { |
| | + | lockForI.lock(); |
| | + | i++; |
| | + | lockForI.unlock(); |
| | + | } |
| | + | public int getI(){ |
| | + | return i; |
| | + | } |
| | + | public void incrementJ() { |
| | + | lockForJ.lock(); |
| | + | j++; |
| | + | lockForJ.unlock(); |
| | + | } |
| | + | public int getJ(){ |
| | + | return j; |
| | + | } |
| | + | } |
| | + | </syntaxhighlight> |
| | + | |
| | + | === Atomic classes === |
| | + | Solves the same problem as locks but for simple operators (AtomicInteger, AtomicBoolean, AtomicIntegerArray, AtomicLong, AtomicBoolean....)<syntaxhighlight lang="java"> |
| | + | import java.util.concurrent.atomic.AtomicInteger; |
| | + | |
| | + | public class BiCounterWithLock { |
| | + | private AtomicInteger i = new AtomicInteger(); |
| | + | private AtomicInteger j = new AtomicInteger(); |
| | + | |
| | + | |
| | + | public void incrementI() { |
| | + | i.incrementAndGet(); |
| | + | } |
| | + | public int getI(){ |
| | + | return i.get(); |
| | + | } |
| | + | public void incrementJ() { |
| | + | j.incrementAndGet(); |
| | + | } |
| | + | public int getJ(){ |
| | + | return j.get(); |
| | + | } |
| | + | } |
| | + | </syntaxhighlight> |
| | + | |
| | + | === Concurrent collections === |
| | + | <syntaxhighlight lang="java"> |
| | + | import java.util.Hashtable; |
| | + | import java.util.Map; |
| | + | import java.util.concurrent.atomic.LongAdder; |
| | + | import java.util.concurrent.ConcurrentMap; |
| | + | import java.util.concurrent.ConcurrentHashMap; |
| | + | |
| | + | // Not thread safe!!! |
| | + | public class MapRunner{ |
| | + | Map<Character, LongAdder> occurrances = new HashTable<>(); |
| | + | |
| | + | String str = "ABCD ABCD ABCD"; |
| | + | for (char character:str.toCharArray()){ |
| | + | LongAdder longAdder = ocurrances.get(character); |
| | + | if (longAdder==null) { |
| | + | longAdder = new LongAdder(); |
| | + | } |
| | + | longAdder.increment(); |
| | + | occurrances.put(character, longAdder); |
| | + | } |
| | + | System.out.println(occurrances); |
| | + | } |
| | + | |
| | + | |
| | + | // Thread safe |
| | + | public class ConcurrentMapRunner{ |
| | + | ConcurrentMap<Character, LongAdder> occurrances = new ConcurrentHashMap<>(); |
| | + | |
| | + | String str = "ABCD ABCD ABCD"; |
| | + | for (char character:str.toCharArray()){ |
| | + | occurances.computeIfAbsent(character, ch -> new LongAdder()).increment(); |
| | + | } |
| | + | System.out.println(occurrances); |
| | } | | } |
| | </syntaxhighlight> | | </syntaxhighlight> |