Skip to content

Commit bb95ae4

Browse files
author
turingfly
committed
Concurrency
1 parent 96f9745 commit bb95ae4

4 files changed

+409
-5
lines changed

Java-8/src/concurrency/IdentifyingThreadingProblems.java

+48-2
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,56 @@
22

33
/**
44
*
5-
* @author chengfeili
5+
* @author chengfeili
66
* Jun 24, 2017 4:00:42 PM
7-
*
7+
*
8+
* Liveness is the ability of an application to be able to execute in a
9+
* timely manner.
10+
*
11+
* there are three types of liveness issues with which you should be
12+
* familiar: deadlock, starvation, and livelock.
13+
*
814
*/
915
public class IdentifyingThreadingProblems {
16+
/**
17+
*
18+
* service.submit(() -> foxy.eatAndDrink(food,water));
19+
*
20+
* service.submit(() -> tails.drinkAndEat(food,water));
21+
*/
22+
public void deadlock() {
23+
24+
}
25+
26+
/**
27+
* Starvation occurs when a single thread is perpetually denied access to a
28+
* shared resource or lock. The thread is still active, but it is unable to
29+
* complete its work as a result of other threads constantly taking the
30+
* resource that they trying to access.
31+
*/
32+
public void starvation() {
33+
34+
}
35+
36+
/**
37+
* Livelock occurs when two or more threads are conceptually blocked
38+
* forever, although they are each still active and trying to complete their
39+
* task
40+
*
41+
* Livelock is often a result of two threads trying to resolve a deadlock
42+
*
43+
* If Foxy and Tails continue this process forever, it is referred to as
44+
* livelock
45+
*/
46+
public void livelock() {
47+
48+
}
49+
50+
/**
51+
* A race condition is an undesirable result that occurs when two tasks,
52+
* which should be completed sequentially, are completed at the same time.
53+
*/
54+
public void raceCondition() {
1055

56+
}
1157
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,150 @@
11
package concurrency;
22

3+
import java.util.Random;
4+
import java.util.concurrent.BrokenBarrierException;
5+
import java.util.concurrent.CyclicBarrier;
6+
import java.util.concurrent.ExecutorService;
7+
import java.util.concurrent.Executors;
8+
import java.util.concurrent.RecursiveAction;
9+
import java.util.concurrent.RecursiveTask;
10+
311
/**
412
*
5-
* @author chengfeili
13+
* @author chengfeili
614
* Jun 24, 2017 4:00:17 PM
715
*
816
*/
917
public class ManagingConcurrentProcesses {
1018

19+
/**
20+
* The CyclicBarrier takes in its constructors a limit value, indicating the
21+
* number of threads to wait for. As each thread nishes, it calls the
22+
* await() method on the cyclic barrier. Once the speci ed number of threads
23+
* have each called await(), the barrier is released and all threads can
24+
* continue.
25+
*/
26+
public void creatingACyclicBarrier() {
27+
28+
}
29+
30+
/**
31+
* When a task gets too complicated, we can split the task into multiple
32+
* other tasks using the fork/join framework.
33+
*
34+
* The fork/join framework relies on the concept of recursion to solve
35+
* complex tasks.
36+
*
37+
* Applying the fork/join framework requires us to perform three steps:
38+
* Create a ForkJoinTask. Create the ForkJoinPool. Start the ForkJoinTask.
39+
*
40+
*/
41+
public void applyingTheForkJoinFramework() {
42+
43+
}
44+
45+
public void workingWithARecursiveTask() {
46+
47+
}
48+
}
49+
50+
class LionPenManager {
51+
private void removeAnimals() {
52+
System.out.println("Removing animals");
53+
}
54+
55+
private void cleanPen() {
56+
System.out.println("Cleaning the pen");
57+
}
58+
59+
private void addAnimals() {
60+
System.out.println("Adding animals");
61+
}
62+
63+
public void performTask(CyclicBarrier c1, CyclicBarrier c2) {
64+
try {
65+
removeAnimals();
66+
c1.await();
67+
cleanPen();
68+
c2.await();
69+
addAnimals();
70+
} catch (InterruptedException | BrokenBarrierException e) {
71+
// Handle checked exceptions here }
72+
}
73+
}
74+
75+
public void test() {
76+
ExecutorService service = null;
77+
try {
78+
service = Executors.newFixedThreadPool(4);
79+
LionPenManager manager = new LionPenManager();
80+
CyclicBarrier c1 = new CyclicBarrier(4);
81+
CyclicBarrier c2 = new CyclicBarrier(4, () -> System.out.println("*** Pen Cleaned!"));
82+
for (int i = 0; i < 4; i++)
83+
service.submit(() -> manager.performTask(c1, c2));
84+
} finally {
85+
if (service != null)
86+
service.shutdown();
87+
}
88+
}
1189
}
90+
91+
/**
92+
* Removing animals Removing animals Removing animals Removing animals Cleaning
93+
* the pen Cleaning the pen Cleaning the pen Cleaning the pen *** Pen Cleaned!
94+
* Adding animals Adding animals Adding animals Adding animals
95+
*/
96+
97+
class WeighAnimalAction extends RecursiveAction {
98+
private int start;
99+
private int end;
100+
private Double[] weights;
101+
102+
public WeighAnimalAction(Double[] weights, int start, int end) {
103+
this.start = start;
104+
this.end = end;
105+
this.weights = weights;
106+
}
107+
108+
protected void compute() {
109+
if (end - start <= 3)
110+
for (int i = start; i < end; i++) {
111+
weights[i] = (double) new Random().nextInt(100);
112+
System.out.println("Animal Weighed: " + i);
113+
}
114+
else {
115+
int middle = start + ((end - start) / 2);
116+
System.out.println("[start=" + start + ",middle=" + middle + ",end=" + end + "]");
117+
invokeAll(new WeighAnimalAction(weights, start, middle), new WeighAnimalAction(weights, middle, end));
118+
}
119+
}
120+
}
121+
122+
class WeighAnimalTask extends RecursiveTask<Double> {
123+
private int start;
124+
private int end;
125+
private Double[] weights;
126+
127+
public WeighAnimalTask(Double[] weights, int start, int end) {
128+
this.start = start;
129+
this.end = end;
130+
this.weights = weights;
131+
}
132+
133+
protected Double compute() {
134+
if (end - start <= 3) {
135+
double sum = 0;
136+
for (int i = start; i < end; i++) {
137+
weights[i] = (double) new Random().nextInt(100);
138+
System.out.println("Animal Weighed: " + i);
139+
sum += weights[i];
140+
}
141+
return sum;
142+
} else {
143+
int middle = start + ((end - start) / 2);
144+
System.out.println("[start=" + start + ",middle=" + middle + ",end=" + end + "]");
145+
RecursiveTask<Double> otherTask = new WeighAnimalTask(weights, start, middle);
146+
otherTask.fork();
147+
return new WeighAnimalTask(weights, middle, end).compute() + otherTask.join();
148+
}
149+
}
150+
}
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,102 @@
11
package concurrency;
22

3+
import java.util.ArrayList;
4+
import java.util.Arrays;
5+
import java.util.Collections;
6+
import java.util.List;
7+
import java.util.Map;
8+
import java.util.concurrent.BlockingDeque;
9+
import java.util.concurrent.ConcurrentHashMap;
10+
import java.util.concurrent.CopyOnWriteArrayList;
11+
import java.util.concurrent.LinkedBlockingDeque;
12+
import java.util.concurrent.TimeUnit;
13+
314
/**
415
*
5-
* @author chengfeili
16+
* @author chengfeili
617
* Jun 24, 2017 3:59:18 PM
718
*
819
*/
920
public class UsingConcurrentCollections {
1021

22+
/**
23+
* the ConcurrentHashMap is ordering read/write access such that all access
24+
* to the class is consistent.
25+
*
26+
* The concurrent classes were created to help avoid common issues in which
27+
* multiple threads are adding and removing objects from the same
28+
* collections. At any given instance, all threads should have the same
29+
* consistent view of the structure of the collection.
30+
*/
31+
public void understandingMemoryConsistencyErrors() {
32+
Map<String, Object> foodData = new ConcurrentHashMap<String, Object>();
33+
foodData.put("penguin", 1);
34+
foodData.put("flamingo", 2);
35+
for (String key : foodData.keySet())
36+
foodData.remove(key);
37+
}
38+
39+
/**
40+
* You should use a concurrent collection class anytime that you are going
41+
* to have multiple threads modify a collections object outside a
42+
* synchronized block or method, even if you don’t expect a concurrency
43+
* problem.
44+
*
45+
* It is considered a good practice to instantiate a concurrent collection
46+
* but pass it around using a non-concurrent interface whenever possible
47+
*/
48+
public void workingWithConcurrentClasses() {
49+
50+
}
51+
52+
public void blockingQueues() {
53+
try {
54+
BlockingDeque<Integer> blockingDeque = new LinkedBlockingDeque<>();
55+
blockingDeque.offer(91);
56+
blockingDeque.offerFirst(5, 2, TimeUnit.MINUTES);
57+
blockingDeque.offerLast(47, 100, TimeUnit.MICROSECONDS);
58+
blockingDeque.offer(3, 4, TimeUnit.SECONDS);
59+
System.out.println(blockingDeque.poll());
60+
System.out.println(blockingDeque.poll(950, TimeUnit.MILLISECONDS));
61+
System.out.println(blockingDeque.pollFirst(200, TimeUnit.NANOSECONDS));
62+
System.out.println(blockingDeque.pollLast(1, TimeUnit.SECONDS));
63+
} catch (InterruptedException e) { // Handle interruption
64+
}
65+
66+
try {
67+
BlockingDeque<Integer> blockingDeque = new LinkedBlockingDeque<>();
68+
blockingDeque.offer(91);
69+
blockingDeque.offerFirst(5, 2, TimeUnit.MINUTES);
70+
blockingDeque.offerLast(47, 100, TimeUnit.MICROSECONDS);
71+
blockingDeque.offer(3, 4, TimeUnit.SECONDS);
72+
System.out.println(blockingDeque.poll());
73+
System.out.println(blockingDeque.poll(950, TimeUnit.MILLISECONDS));
74+
System.out.println(blockingDeque.pollFirst(200, TimeUnit.NANOSECONDS));
75+
System.out.println(blockingDeque.pollLast(1, TimeUnit.SECONDS));
76+
} catch (InterruptedException e) { // Handle interruption
77+
}
78+
}
79+
80+
/**
81+
* The SkipList classes, ConcurrentSkipListSet and ConcurrentSkipListMap,
82+
* are concurrent versions of their sorted counterparts, TreeSet and TreeMap
83+
*/
84+
public void skipListCollections() {
85+
List<Integer> list = new CopyOnWriteArrayList<>(Arrays.asList(4, 3, 52));
86+
for (Integer item : list) {
87+
System.out.print(item + " ");
88+
list.add(9);
89+
}
90+
System.out.println();
91+
System.out.println("Size: " + list.size());
92+
// output 4 3 52 Size: 6
93+
}
94+
95+
public void obtainingSynchronizedCollections() {
96+
List<Integer> list = Collections.synchronizedList(new ArrayList<>(Arrays.asList(4, 3, 52)));
97+
synchronized (list) {
98+
for (int data : list)
99+
System.out.print(data + " ");
100+
}
101+
}
11102
}

0 commit comments

Comments
 (0)