併發編程相關類代碼示例-工具篇

1、ReentrantLock、Condition

public class test {
    private int outPutNum = 1;
    boolean t1_run_flag = true;
    @Test
    public void main() {
        Lock lock = new ReentrantLock();
        Condition condThread1 = lock.newCondition();
        Condition condThread2 = lock.newCondition();
        Thread thread_1 = new Thread() {
            public void run() {
                try {
                    lock.lock();
                    while (outPutNum <= 100) {
                        if (!t1_run_flag) {
                            condThread1.await();
                        }
                        if(outPutNum > 100) {
                            break;
                        }
                        System.out.println("thread_1:" + outPutNum);
                        outPutNum++;
                        t1_run_flag = false;
                        condThread2.signal();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };
        Thread thread_2 = new Thread() {
            public void run() {
                try {
                    lock.lock();
                    while (outPutNum <= 100) {
                        if (t1_run_flag) {
                            condThread2.await();
                        }
                        if(outPutNum > 100) {
                            break;
                        }
                        System.out.println("thread_2:" + outPutNum);
                        outPutNum++;
                        t1_run_flag = true;
                        condThread1.signal();
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        };
        thread_1.start();
        thread_2.start();
    }
}

2、CountDownLatch

public class ToolDemo1 {

    private int[] nums;

    public ToolDemo1(int line) {
        nums = new int[line];
    }

    public void calc(String line, int index, CountDownLatch latch) {
        String[] nus = line.split(",");
        int total = 0;
        for(String num : nus) {
            total += Integer.parseInt(num);
        }
        nums[index] = total;
        System.out.println(Thread.currentThread().getName() + "執行計算任務" + line + "結果爲:" + total);
        latch.countDown();
    }

    public void sum() {
        System.out.println("彙總線程開始執行...");
        int total = 0;
        for(int i = 0; i < nums.length; i++) {
            total += nums[i];
        }
        System.out.println("最終的結果爲:" + total);
    }

    public static void main(String[] args) {
        List<String> contents = readFile();
        int lineCount = contents.size();

        CountDownLatch latch = new CountDownLatch(lineCount);

        ToolDemo1 d = new ToolDemo1(lineCount);
        for(int i = 0; i < lineCount; i++) {
            final int j = i;
            new Thread(new Runnable() {
                @Override
                public void run() {
                    d.calc(contents.get(j), j, latch);
                }
            }).start();
        }
        try {
            latch.await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        d.sum();
    }

    private static List<String> readFile() {
        List<String> contents = new ArrayList<>();
        String line = null;
        BufferedReader br = null;
        try {
            String root = System.getProperty("user.dir");
            br = new BufferedReader(new FileReader(root + "/nums.txt"));
            while ((line = br.readLine()) != null) {
                contents.add(line);
            }
        }catch (Exception e) {
            e.printStackTrace();
        } finally {
            if(br != null) {
                try {
                    br.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return contents;
    }
}

3、CyclicBarrier(與CountDownLatch區別是採用加計數,await()使計數+1,可以重置)

public class ToolDemo2 {

    Random random = new Random();
    public void meeting(CyclicBarrier barrier) {
        try {
            Thread.sleep(random.nextInt(2000));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + "到達會議室,等待會議開始...");
        try {
            barrier.await();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ToolDemo2 toolDemo2 = new ToolDemo2();

        CyclicBarrier barrier = new CyclicBarrier(10, new Runnable() {
            @Override
            public void run() {
                System.out.println("開始開會...");
            }
        });

        for(int i = 0; i < 10; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    toolDemo2.meeting(barrier);
                }
            }).start();
        }
    }
}

3、Semaphore

public class ToolDemo3 {

    public void method(Semaphore semaphore) {
        try {
            semaphore.acquire();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName() + " is run...");
        try {
            Thread.sleep(2000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        semaphore.release();
    }

    public static void main(String[] args) {
        ToolDemo3 toolDemo3 = new ToolDemo3();
        Semaphore semaphore = new Semaphore(10);

        for(int i = 0; i < 50; i++) {
            new Thread(new Runnable() {
                @Override
                public void run() {
                    toolDemo3.method(semaphore);
                }
            }).start();
        }
    }
}

4、Exchanger

public class ToolDemo4 {

    public void exchangeA(Exchanger<String> exch) {
        System.out.println("exchangeA 方法執行...");

        try {
            System.out.println("exchangeA 線程正在抓取數據...");
            Thread.sleep(2000);
            System.out.println("exchangeA 線程抓取數據結束...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        String res = "12345";
        try {
            System.out.println("等待對比結果...");
            exch.exchange(res);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public void exchangeB(Exchanger<String> exch) {
        System.out.println("exchangeB 方法執行...");

        try {
            System.out.println("exchangeB 線程正在抓取數據...");
            Thread.sleep(2000);
            System.out.println("exchangeB 線程抓取數據結束...");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        String res = "12345";
        try {
            String value = exch.exchange(res);
            System.out.println("開始進行比對...");
            System.out.println("對比結果: " + value.equals(res));
            exch.exchange(res);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        ToolDemo4 toolDemo4 = new ToolDemo4();
        Exchanger<String> exch = new Exchanger<>();
        new Thread(new Runnable() {
            @Override
            public void run() {
                toolDemo4.exchangeA(exch);
            }
        }).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                toolDemo4.exchangeB(exch);
            }
        }).start();
    }
}

5、ForkJoin

public class ToolDemo5 extends RecursiveTask<Integer> {

    private int begin;
    private int end;

    public ToolDemo5(int begin, int end) {
        this.begin = begin;
        this.end = end;
    }

    @Override
    protected Integer compute() {
        int sum = 0;
        // 拆分任務
        if(end - begin <= 2) {
            // 計算
            for(int i = begin; i <= end; i++) {
                sum += i;
            }
            return sum;
        } else {
            // 拆分
            ToolDemo5 d1 = new ToolDemo5(begin, (begin + end) / 2);
            ToolDemo5 d2 = new ToolDemo5((begin + end) / 2 + 1, end);

            //執行任務
            d1.fork();
            d2.fork();

            Integer res1 = d1.join();
            Integer res2 = d2.join();

            sum = res1 + res2;
        }
        return sum;
    }

    public static void main(String[] args) throws Exception {
        ForkJoinPool pool = new ForkJoinPool();
        Future<Integer> feature = pool.submit(new ToolDemo5(1, 100));
        System.out.println("...");
        System.out.println("計算的值爲:" + feature.get());
    }
}

6、BlockingQueue

public class EShop implements Shop{

   private final int MAX_COUNT = 10;

    private BlockingQueue<Integer> queue = new ArrayBlockingQueue<>(MAX_COUNT);

    @Override
    public void push() {
        try {
            queue.put(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
    @Override
    public void take() {
       try {
           queue.take();
       } catch (InterruptedException e) {
           e.printStackTrace();
       }
    }

    public void size() {
        while(true) {
            System.out.println("當前隊列的長度:" + queue.size());
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class PushTarget implements Runnable {

    private Shop eShop;

    public PushTarget(Shop eShop) {
        this.eShop = eShop;
    }

    @Override
    public void run() {
        while (true) {
            eShop.push();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public interface Shop {

    void push();
    void take();
    void size();
}

public class TakeTarget implements Runnable {

    private Shop eShop;

    public TakeTarget(Shop eShop) {
        this.eShop = eShop;
    }

    @Override
    public void run() {
        while (true) {
            eShop.take();
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class ToolDemo6 {

    public static void main(String[] args) {
        Shop eShop = new EShop();

        TakeTarget takeTarget = new TakeTarget(eShop);
        PushTarget pushTarget = new PushTarget(eShop);

        new Thread(pushTarget).start();
        new Thread(pushTarget).start();
        new Thread(pushTarget).start();
        new Thread(pushTarget).start();
        new Thread(pushTarget).start();

        new Thread(takeTarget).start();
        new Thread(takeTarget).start();
        new Thread(takeTarget).start();
        new Thread(takeTarget).start();
        new Thread(takeTarget).start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                eShop.size();
            }
        }).start();
    }
}

7、StampedLock(與ReetrantReadWriteLock區別在於這個是樂觀鎖)

public class ToolDemo7 {

    private int balance;
    private StampedLock lock = new StampedLock();

    public void conditionReadWrite(int value) {
        // 首先判斷balance是否滿足條件
        long stamp = lock.readLock();
        while(balance > 0) {
            long writeStamp = lock.tryConvertToWriteLock(stamp);
            // 成功轉換成寫鎖
            if(writeStamp != 0) {
                stamp = writeStamp;
                balance += value;
                break;
            } else {
                // 沒有轉換成寫鎖,這裏需要首先釋放讀鎖,然後在拿到寫鎖
                lock.unlockRead(stamp);
                // 獲取寫鎖
                stamp = lock.writeLock();
            }
        }
        lock.unlock(stamp);
    }

    public void optimisticRead() {
        long stamp = lock.tryOptimisticRead();
        int res = balance;
        // 這裏可能會出現寫操作,因此要進行判斷
        if(!lock.validate(stamp)) {
            // 重新獲取讀鎖
            long readStamp = lock.readLock();
            res = balance;
            stamp = readStamp;
        }
        lock.unlockRead(stamp);
    }

    public void read() {
        long stamp = lock.readLock();
        int res = balance;
        // 釋放讀鎖
        lock.unlockRead(stamp);
    }

    public void write(int value) {
        long stamp = lock.writeLock();
        balance += value;
        lock.unlockWrite(stamp);
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章