diff --git a/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicCount.java b/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicCount.java index 21e28987..cece1ec3 100644 --- a/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicCount.java +++ b/03concurrency/0301/src/main/java/java0/conc0302/atomic/AtomicCount.java @@ -7,7 +7,7 @@ public class AtomicCount { private AtomicInteger num = new AtomicInteger(); - public synchronized int add() { + public int add() { return num.getAndIncrement(); } diff --git a/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo2.java b/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo2.java index 7e8194a0..82b4001b 100644 --- a/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo2.java +++ b/03concurrency/0301/src/main/java/java0/conc0302/lock/ReentrantReadWriteLockDemo2.java @@ -41,7 +41,7 @@ public Object readWrite(String key) { public static void main(String[] args) { ReentrantReadWriteLockDemo2 demo2 = new ReentrantReadWriteLockDemo2(); - demo2.readWrite("wangwei"); + demo2.readWrite("bingfabiancheng"); } } diff --git a/03concurrency/0301/src/main/java/java0/conc0303/Homework03.java b/03concurrency/0301/src/main/java/java0/conc0303/Homework03.java new file mode 100644 index 00000000..3e64fc85 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/Homework03.java @@ -0,0 +1,37 @@ +package java0.conc0303; + +/** + * 本周作业:(必做)思考有多少种方式,在main函数启动一个新线程或线程池, + * 异步运行一个方法,拿到这个方法的返回值后,退出主线程? + * 写出你的方法,越多越好,提交到github。 + * + * 一个简单的代码参考: + */ +public class Homework03 { + + public static void main(String[] args) { + + long start=System.currentTimeMillis(); + // 在这里创建一个线程或线程池, + // 异步执行 下面方法 + + int result = sum(); //这是得到的返回值 + + // 确保 拿到result 并输出 + System.out.println("异步计算结果为:"+result); + + System.out.println("使用时间:"+ (System.currentTimeMillis()-start) + " ms"); + + // 然后退出main线程 + } + + private static int sum() { + return fibo(36); + } + + private static int fibo(int a) { + if ( a < 2) + return 1; + return fibo(a-1) + fibo(a-2); + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/ConcurrentHashMapDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/ConcurrentHashMapDemo.java new file mode 100644 index 00000000..1ec7f12b --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/ConcurrentHashMapDemo.java @@ -0,0 +1,46 @@ +package java0.conc0303.collection; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.atomic.AtomicInteger; + +public class ConcurrentHashMapDemo { + + public static void main(String[] args) { + demo1(); + } + + public static void demo1() { + final Map count = new ConcurrentHashMap<>(); + final CountDownLatch endLatch = new CountDownLatch(2); + Runnable task = new Runnable() { + @Override + public void run() { + AtomicInteger oldValue; + for (int i = 0; i < 5; i++) { + oldValue = count.get("a"); + if (null == oldValue) { + AtomicInteger zeroValue = new AtomicInteger(0); + oldValue = count.putIfAbsent("a", zeroValue); + if (null == oldValue) { + oldValue = zeroValue; + } + } + oldValue.incrementAndGet(); + } + endLatch.countDown(); + } + }; + new Thread(task).start(); + new Thread(task).start(); + + try { + endLatch.await(); + System.out.println(count); + } catch (Exception e) { + e.printStackTrace(); + } + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo.java new file mode 100644 index 00000000..9b305cbd --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo.java @@ -0,0 +1,69 @@ +package java0.conc0303.collection; + +import java.util.ArrayList; +import java.util.LinkedList; +import java.util.List; +import java.util.Vector; +import java.util.concurrent.CopyOnWriteArrayList; + +public class CopyOnWriteArrayListDemo { + + public static void main(String[] args) { + + // ArrayList,LinkedList,Vector不安全,运行报错 + // why Vector 也不安全 +// List list = new ArrayList(); +// List list = new LinkedList<>(); +// List list = new Vector<>(); + + // 只有CopyOnWriteArrayList 安全,不报错 + List list = new CopyOnWriteArrayList(); + + for (int i = 0; i < 10000; i++) + { + list.add(i); + } + + T1 t1 = new T1(list); + T2 t2 = new T2(list); + t1.start(); + t2.start(); + + } + + public static class T1 extends Thread + { + private List list; + + public T1(List list) + { + this.list = list; + } + + public void run() + { + for (Integer i : list) + { + } + } + } + + public static class T2 extends Thread + { + private List list; + + public T2(List list) + { + this.list = list; + } + + public void run() + { + for (int i = 0; i < list.size(); i++) + { + list.remove(i); + } + } + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo1.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo1.java new file mode 100644 index 00000000..b99bf181 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo1.java @@ -0,0 +1,69 @@ +package java0.conc0303.collection; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + + +public class CopyOnWriteArrayListDemo1 { + private static final int THREAD_POOL_MAX_NUM = 10; + //private List mList = new ArrayList(); // ArrayList 无法运行 + private List mList = new CopyOnWriteArrayList<>(); + + public static void main(String args[]) { + new CopyOnWriteArrayListDemo1().start(); + } + + private void initData() { + for (int i = 0; i <= THREAD_POOL_MAX_NUM; i++) { + this.mList.add("...... Line " + (i + 1) + " ......"); + } + } + + private void start() { + initData(); + ExecutorService service = Executors.newFixedThreadPool(THREAD_POOL_MAX_NUM); + for (int i = 0; i < THREAD_POOL_MAX_NUM; i++) { + service.execute(new ListReader(this.mList)); + service.execute(new ListWriter(this.mList, i)); + } + service.shutdown(); + } + + private class ListReader implements Runnable { + private List mList; + + public ListReader(List list) { + this.mList = list; + } + + @Override + public void run() { + if (this.mList != null) { + for (String str : this.mList) { + System.out.println(Thread.currentThread().getName() + " : " + str); + } + } + } + } + + private class ListWriter implements Runnable { + private List mList; + private int mIndex; + + public ListWriter(List list, int index) { + this.mList = list; + this.mIndex = index; + } + + @Override + public void run() { + if (this.mList != null) { + //this.mList.remove(this.mIndex); + this.mList.add("...... add " + mIndex + " ......"); + } + } + } +} \ No newline at end of file diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo2.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo2.java new file mode 100644 index 00000000..94ae2427 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/CopyOnWriteArrayListDemo2.java @@ -0,0 +1,51 @@ +package java0.conc0303.collection; + +import java.util.concurrent.CopyOnWriteArrayList; + +public class CopyOnWriteArrayListDemo2 { + + private final static CopyOnWriteArrayList list = new CopyOnWriteArrayList(); + + public static void main(String[] args) { + // 这个例子再次证明, + // 多个步骤的操作,不能保证原子性 + // list.size() 获取到的数,再继续用list时,可能已经变了 + // + test(); + } + public static void test(){ + for(int i = 0; i<10000; i++){ + list.add("string" + i); + } + + new Thread(new Runnable() { + @Override + public void run() { + while (true) { + if (list.size() > 0) { // todo : 下一个get操作执行时,size可能已经是0了 + String content = list.get(list.size() - 1); + }else { + break; + } + } + } + }).start(); + + new Thread(new Runnable() { + @Override + public void run() { + while (true) { + if(list.size() <= 0){ + break; + } + list.remove(0); + try { + Thread.sleep(10); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + } + }).start(); + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/LinkedHashMapDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/LinkedHashMapDemo.java new file mode 100644 index 00000000..5786dd7b --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/LinkedHashMapDemo.java @@ -0,0 +1,43 @@ +package java0.conc0303.collection; + +import java.util.HashMap; +import java.util.Iterator; +import java.util.LinkedHashMap; +import java.util.Map; +import java.util.Set; + +public class LinkedHashMapDemo { + public static void main(String[] args) { + + // test hash map + System.out.println("=====>1. test hash map"); + Map hashMap = new HashMap(); + hashMap.put("name1", "josan1"); + hashMap.put("name2", "josan2"); + hashMap.put("name3", "josan3"); + Set> set = hashMap.entrySet(); + Iterator> iterator = set.iterator(); + while(iterator.hasNext()) { + Map.Entry entry = iterator.next(); + String key = (String) entry.getKey(); + String value = (String) entry.getValue(); + System.out.println("key:" + key + ",value:" + value); + } + + // test linked hash map + System.out.println("=====>2. test linked hash map"); + Map linkedHashMap = new LinkedHashMap<>(); + linkedHashMap.put("name1", "josan1"); + linkedHashMap.put("name2", "josan2"); + linkedHashMap.put("name3", "josan3"); + Set> set1 = linkedHashMap.entrySet(); + Iterator> iterator1 = set1.iterator(); + while(iterator1.hasNext()) { + Map.Entry entry = iterator1.next(); + String key = (String) entry.getKey(); + String value = (String) entry.getValue(); + System.out.println("key:" + key + ",value:" + value); + } + + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/SyncListDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/SyncListDemo.java new file mode 100644 index 00000000..95e2be28 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/SyncListDemo.java @@ -0,0 +1,47 @@ +package java0.conc0303.collection; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +public class SyncListDemo { + + public static void main(String[] args) { + List list0 = Arrays.asList(1,2,3,4,5,6,7,8,8); + list0.set(8,9); // 可以修改内容,不能变动元素数量 + // list0.add(10) will throw an error + + List list = new ArrayList(); // 正常List,可以操作 + list.addAll(list0); + + List list1 = Collections.synchronizedList(list); + + // 多线程操作 + // to do something + + System.out.println(Arrays.toString(list1.toArray())); + + Collections.shuffle(list1); + + + + System.out.println(Arrays.toString(list1.toArray())); + + + // 假如不再修改 + + List list2 = Collections.unmodifiableList(list1); + + System.out.println(list2.getClass()); + + list2.set(8,10); + + System.out.println(Arrays.toString(list2.toArray())); + + list2.add(11); + + System.out.println(Arrays.toString(list2.toArray())); + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/collection/TreeMapDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/collection/TreeMapDemo.java new file mode 100644 index 00000000..bb04f20e --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/collection/TreeMapDemo.java @@ -0,0 +1,25 @@ +package java0.conc0303.collection; + +import java.util.Comparator; +import java.util.TreeMap; + +public class TreeMapDemo { + + public static void main(String[] args) { + + // + TreeMap map = new TreeMap<>(Comparator.reverseOrder()); + map.put(3, "val"); + map.put(2, "val"); + map.put(1, "val"); + map.put(5, "val"); + map.put(4, "val"); + // {5=val, 4=val, 3=val, 2=val, 1=val} + System.out.println(map); + + TreeMap map1 = new TreeMap<>(Comparator.naturalOrder()); + map1.putAll(map); + System.out.println(map1); + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/future/CompletableFutureDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/future/CompletableFutureDemo.java new file mode 100644 index 00000000..2a21f4f5 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/future/CompletableFutureDemo.java @@ -0,0 +1,81 @@ +package java0.conc0303.future; + +import java.util.concurrent.CompletableFuture; + +public class CompletableFutureDemo { + + public static void main(String[] args){ + + // 1.变换结果 + System.out.println("=====>1.变换结果"); + String result1 = CompletableFuture.supplyAsync(()->{return "Hello ";}).thenApplyAsync(v -> v + "world").join(); + System.out.println(result1); + + // 2.消费 + CompletableFuture.supplyAsync(()->{return "Hello ";}).thenAccept(v -> { System.out.println("=====>2.消费");System.out.println("consumer: " + v);}); + + // 3.组合 + System.out.println("=====>3.组合"); + String result3 = CompletableFuture.supplyAsync(()->{ + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return "Hello"; + }).thenCombine(CompletableFuture.supplyAsync(()->{ + try { + Thread.sleep(2000); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return "world"; + }),(s1,s2)->{return s1 + " " + s2;}).join(); + System.out.println("thenCombine:"+result3); + + CompletableFuture.supplyAsync(() -> "Hello, java course.") + .thenApply(String::toUpperCase).thenCompose(s -> CompletableFuture.supplyAsync(s::toLowerCase)).thenAccept(v -> { System.out.println("thenCompose:"+v);}); + + // 4.竞争 + System.out.println("=====>4.竞争"); + String result4 = CompletableFuture.supplyAsync(()->{ + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return "Hi Boy"; + }).applyToEither(CompletableFuture.supplyAsync(()->{ + try { + Thread.sleep(300); + } catch (InterruptedException e) { + e.printStackTrace(); + } + return "Hi Girl"; + }),(s)->{return s;}).join(); + System.out.println(result4); + + // 5.补偿异常 + System.out.println("=====>5.补偿异常"); + String result5 = CompletableFuture.supplyAsync(()->{ + try { + Thread.sleep(100); + } catch (InterruptedException e) { + e.printStackTrace(); + } + if(true) { + throw new RuntimeException("exception test!"); + } + + return "Hi Boy"; + }).exceptionally(e->{ + System.out.println(e.getMessage()); + return "Hello world!"; + }).join(); + System.out.println(result5); + + + + } + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/future/FutureDemo1.java b/03concurrency/0301/src/main/java/java0/conc0303/future/FutureDemo1.java new file mode 100644 index 00000000..14a16383 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/future/FutureDemo1.java @@ -0,0 +1,23 @@ +package java0.conc0303.future; + +import java.util.Random; +import java.util.concurrent.*; + +public class FutureDemo1 { + public static void main(String[] args) { + ExecutorService executor = Executors.newCachedThreadPool(); + Future result = executor.submit(new Callable() { + public Integer call() throws Exception { + return new Random().nextInt(); + } + }); + executor.shutdown(); + try { + System.out.println("result:" + result.get()); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } +} \ No newline at end of file diff --git a/03concurrency/0301/src/main/java/java0/conc0303/future/FutureTask1.java b/03concurrency/0301/src/main/java/java0/conc0303/future/FutureTask1.java new file mode 100644 index 00000000..69499819 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/future/FutureTask1.java @@ -0,0 +1,35 @@ +package java0.conc0303.future; + +import java.util.Random; +import java.util.concurrent.*; + +public class FutureTask1 { + public static void main(String[] args) { + //第一种方式 + FutureTask task = new FutureTask(new Callable() { + @Override + public Integer call() throws Exception { + return new Random().nextInt(); + } + }); + new Thread(task).start(); + //第二种方方式 +// ExecutorService executor = Executors.newSingleThreadExecutor(); +// FutureTask task = new FutureTask(new Callable() { +// @Override +// public Integer call() throws Exception { +// return new Random().nextInt(); +// } +// }); +// executor.submit(task); + + try { + System.out.println("result: " + task.get()); + } catch (InterruptedException e) { + e.printStackTrace(); + } catch (ExecutionException e) { + e.printStackTrace(); + } + } + +} \ No newline at end of file diff --git a/03concurrency/0301/src/main/java/java0/conc0303/stream/StreamParallelDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/stream/StreamParallelDemo.java new file mode 100644 index 00000000..5b02350b --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/stream/StreamParallelDemo.java @@ -0,0 +1,34 @@ +package java0.conc0303.stream; + +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingQueue; +import java.util.stream.Collectors; +import java.util.stream.IntStream; + +public class StreamParallelDemo { + public static void main(String[] args) { + List list = new ArrayList<>(); + IntStream.range(1, 10000).forEach(i -> list.add(i)); + BlockingQueue blockingQueue = new LinkedBlockingQueue(10000); + List longList = list.stream().parallel() + .map(i -> i.longValue()) + .sorted() + .collect(Collectors.toList()); +// // 串行,单线程 +// longList.stream().forEach( + // 并行,默认使用CPU * 2个线程 + longList.stream().parallel().forEach( + i -> { + try { + blockingQueue.put(i); + } catch (InterruptedException e) { + e.printStackTrace(); + } + }); + System.out.println("blockingQueue:" + blockingQueue.toString()); + } + + +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java new file mode 100644 index 00000000..bbfe35e0 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/threadlocal/ThreadLocalDemo.java @@ -0,0 +1,48 @@ +package java0.conc0303.threadlocal; + +public class ThreadLocalDemo { + + private static ThreadLocal seqNum = new ThreadLocal() { + public Integer initialValue() { + return 0; + } + }; + + public ThreadLocal getThreadLocal() { + return seqNum; + } + + public int getNextNum() { + seqNum.set(seqNum.get() + 1); + return seqNum.get(); + } + + + public static void main(String[] args) { + ThreadLocalDemo threadLocalMain = new ThreadLocalDemo(); + + SnThread client1 = new SnThread(threadLocalMain); + SnThread client2 = new SnThread(threadLocalMain); + SnThread client3 = new SnThread(threadLocalMain); + + client1.start(); + client2.start(); + client3.start(); + } + + + private static class SnThread extends Thread { + private ThreadLocalDemo sn; + + public SnThread(ThreadLocalDemo sn) { + this.sn = sn; + } + + public void run() { + for (int i = 0; i < 3; i++) { + System.out.println("thread[" + Thread.currentThread().getName() + "] ---> sn [" + sn.getNextNum() + "]"); + } + sn.getThreadLocal().remove(); + } + } +} diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo.java new file mode 100644 index 00000000..b93731be --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo.java @@ -0,0 +1,33 @@ +package java0.conc0303.tool; + +import java.util.concurrent.CountDownLatch; + +public class CountDownLatchDemo { + public static void main(String[] args) throws InterruptedException { + CountDownLatch countDownLatch = new CountDownLatch(5); + for(int i=0;i<5;i++){ + new Thread(new readNum(i,countDownLatch)).start(); + } + countDownLatch.await(); // 注意跟CyclicBarrier不同,这里在主线程await + System.out.println("==>各个子线程执行结束。。。。"); + System.out.println("==>主线程执行结束。。。。"); + } + + static class readNum implements Runnable{ + private int id; + private CountDownLatch latch; + public readNum(int id,CountDownLatch latch){ + this.id = id; + this.latch = latch; + } + @Override + public void run() { + synchronized (this){ + System.out.println("id:"+id+","+Thread.currentThread().getName()); + //latch.countDown(); + System.out.println("线程组任务"+id+"结束,其他任务继续"); + latch.countDown(); + } + } + } +} \ No newline at end of file diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo2.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo2.java new file mode 100644 index 00000000..eff0ba40 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/CountDownLatchDemo2.java @@ -0,0 +1,40 @@ +package java0.conc0303.tool; + + +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; + +public class CountDownLatchDemo2 { + + private final static int threadCount = 200; + + public static void main(String[] args) throws Exception { + + ExecutorService exec = Executors.newCachedThreadPool(); + + final CountDownLatch countDownLatch = new CountDownLatch(threadCount); + + for (int i = 0; i < threadCount; i++) { + final int threadNum = i; + exec.execute(() -> { + try { + test(threadNum); + } catch (Exception e) { + e.printStackTrace(); + } finally { + countDownLatch.countDown(); + } + }); + } + countDownLatch.await(); + System.out.println("==>所有程序员完成任务,项目顺利上线!"); + exec.shutdown(); + } + + private static void test(int threadNum) throws Exception { + Thread.sleep(100); + System.out.println(String.format("程序员[%d]完成任务。。。", threadNum)); + Thread.sleep(100); + } +} \ No newline at end of file diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo.java new file mode 100644 index 00000000..bc8417d7 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo.java @@ -0,0 +1,48 @@ +package java0.conc0303.tool; + +import java.util.concurrent.CyclicBarrier; + +public class CyclicBarrierDemo { + public static void main(String[] args) throws InterruptedException { + CyclicBarrier cyclicBarrier = new CyclicBarrier(5, new Runnable() { + @Override + public void run() { + System.out.println("回调>>"+Thread.currentThread().getName()); + System.out.println("回调>>线程组执行结束"); + } + }); + for (int i = 0; i < 5; i++) { + new Thread(new readNum(i,cyclicBarrier)).start(); + } + + System.out.println("==>各个子线程执行结束。。。。"); + System.out.println("==>主线程执行结束。。。。"); + + //CyclicBarrier 可以重复利用, + // 这个是CountDownLatch做不到的 +// for (int i = 11; i < 16; i++) { +// new Thread(new readNum(i,cyclicBarrier)).start(); +// } + } + static class readNum implements Runnable{ + private int id; + private CyclicBarrier cyc; + public readNum(int id,CyclicBarrier cyc){ + this.id = id; + this.cyc = cyc; + } + @Override + public void run() { + synchronized (this){ + System.out.println("id:"+id+","+Thread.currentThread().getName()); + try { + //cyc.await(); + System.out.println("线程组任务" + id + "结束,其他任务继续"); + cyc.await(); // 注意跟CountDownLatch不同,这里在子线程await + } catch (Exception e) { + e.printStackTrace(); + } + } + } + } +} \ No newline at end of file diff --git a/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo2.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo2.java new file mode 100644 index 00000000..9c83bc26 --- /dev/null +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/CyclicBarrierDemo2.java @@ -0,0 +1,49 @@ +package java0.conc0303.tool; + +import java.util.concurrent.BrokenBarrierException; +import java.util.concurrent.CyclicBarrier; + +public class CyclicBarrierDemo2 { + public static void main(String[] args) { + int N = 4; + CyclicBarrier barrier = new CyclicBarrier(N); + + for(int i=0;i { + try { + semaphore.acquire(3); // 获取全部许可,退化成串行执行 + test(threadNum); + semaphore.release(3); // 释放多个许可 + } catch (Exception e) { + e.printStackTrace(); + } + }); + } + exec.shutdown(); + } + + private static void test(int threadNum) throws Exception { + System.out.println("id:"+threadNum+","+Thread.currentThread().getName()); + Thread.sleep(1000); + } + } diff --git a/03concurrency/0301/src/main/java/java0/conc0302/tool/SemaphoreDemo.java b/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo3.java similarity index 84% rename from 03concurrency/0301/src/main/java/java0/conc0302/tool/SemaphoreDemo.java rename to 03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo3.java index 6f43ffb1..3a02dc78 100644 --- a/03concurrency/0301/src/main/java/java0/conc0302/tool/SemaphoreDemo.java +++ b/03concurrency/0301/src/main/java/java0/conc0303/tool/SemaphoreDemo3.java @@ -1,9 +1,9 @@ -package java0.conc0302.tool; +package java0.conc0303.tool; import java.util.concurrent.Semaphore; -public class SemaphoreDemo { +public class SemaphoreDemo3 { public static void main(String[] args) { // 启动线程 @@ -41,17 +41,6 @@ public void run() { static class Consumer implements Runnable { - /** - * When an object implementing interface Runnable is used - * to create a thread, starting the thread causes the object's - * run method to be called in that separately executing - * thread. - *

- * The general contract of the method run is that it may - * take any action whatsoever. - * - * @see Thread#run() - */ @Override public void run() { while (true) {