Java 線程協作實例

線程協作

  • 存款/提款

    • 提款金額大於存款金額:提款線程必須等待存款線程存錢
    • 存款線程存入錢之後,通知提錢線程重新嘗試提錢,若餘額 < 提款金額,提款線程必須繼續等待新的存款

在這裏插入圖片描述

  • 線程之間的相互協作

    • Condition對象:await,signal(喚醒一個),signalAll(喚醒所有)

      • Condition 對象是通過調用Lock的newCondition()方法:創建
      • 同一個條件對象調用signal和signalAll()方法喚醒等待的線程
  • 調用await之後,lock對象會被釋放,喚醒存錢線程

    • java5之前:對象的內置監視器(Object類的wait/signal/signalAll)
    package Unit30.CorpThread;
    
    
    import java.util.concurrent.ExecutorService;
    import java.util.concurrent.Executors;
    import java.util.concurrent.locks.Condition;
    import java.util.concurrent.locks.Lock;
    import java.util.concurrent.locks.ReentrantLock;
    
    public class ThreadCooperation {
        private static Lock lock = new ReentrantLock();
        private static Condition newDespoit = lock.newCondition();
    
        private static class Acconut {
            private int balance = 0;
    
            public int getBalance() {
                return balance;
            }
    		//取錢
            private void withDraw(int amount) {
                try {
                    lock.lock();
                    ;
                    while (balance < amount) {
                        System.out.print("\t\t\tWait for deposit");
                        /**
                         * 和sleep不同,newDespoit.await();會導致當前線程掛起
                         * 同時鎖被釋放,否則存錢線程永遠無法進入deposit方法
                         * */
                        newDespoit.await();
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
                balance -= amount;
                System.out.println("\t\t\tWithDraw " + amount + "\t\t\t\t" + getBalance());
            }
    		//存錢
            public void deposit(int amount) {
                try {
                    lock.lock();
                    balance += amount;
                    System.out.println("\t\t\tdeposit " + amount + " \t\t\t\t\t\t" + getBalance());
                    /**
                     * 調用newDespoit.signalAll();
                     * 去喚醒所有因newDespoit.await();而掛起的線程
                     * */
                    newDespoit.signalAll();
                } finally {
                    lock.unlock();
                }
            }
        }
    
    
        private static Acconut acconut = new Acconut();
    
        public static class DepositTask implements Runnable {
    
            @Override
            public void run() {
                try {
                    while (true) {
                        acconut.deposit((int) (Math.random() * 10) + 1);
                        Thread.sleep(5);
                    }
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        public static class WithDrawTask implements Runnable {
            public void run() {
                while (true) {
                    acconut.withDraw((int)(Math.random()*10)+1);
                }
            }
        }
    
        public static void main(String[] args) {
            ExecutorService executorService = Executors.newFixedThreadPool(2);
            executorService.execute(new DepositTask());
            executorService.execute(new WithDrawTask());
            executorService.shutdown();
            System.out.println("Thread 1\t\t\t Thread \t\t\t\t Balance");
        }
    }
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章