1. 程式人生 > >執行緒通訊和同步的兩種實現方…

執行緒通訊和同步的兩種實現方…

    在多執行緒程式設計中,不免要涉及同步和通訊兩個方面。同步有兩種方法實現,一種是利用synchronized標示,另外一種是加鎖。生成鎖的物件的方法是:private static Lock lock = new ReentrantLock();Lock是一個介面,而Reentrantlock是一個實現的類。構造方法有:ReentrantLock()和ReentrantLock(fair:boolean)兩種。其中第二種傳遞的是一個boolean值的引數,當設定為true時系統會按照等待的先後時間讓執行緒活得鎖,但是效率和效能不如預設值的好,但是同時也可以避免資源匱乏。synchronized可以宣告方法,也可以用來標記某段程式碼。用來標記某段程式碼時的用法是:synchronized(){}。     通訊方面有兩種方法,第一種是利用鎖生成Condition物件,然後呼叫await()和signal()或者signalall(),另外一種是利用繼承的object類中的wait()和notify()或者notifyall()喚醒方法。個人覺得利用鎖生成的condition物件的方法會比較靈活。下面是實現的存款和取款的小程式。第一種實現的方法是lock加condition: package com.ccy.test; 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 Account account = new Account(); public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(2); executor.execute(new DepositeTask()); executor.execute(new WithdrawTask()); executor.shutdown(); System.out.println("Thread 1ttThread2ttBalance"); } private static class DepositeTask implements Runnable { @Override public void run() { // TODO Auto-generated method stub try { while (true) { account.deposite((int) (Math.random() * 10) + 1); Thread.sleep(1000); } } catch (Exception ex) { ex.printStackTrace(); } } } private static class WithdrawTask implements Runnable { @Override public void run() { // TODO Auto-generated method stub while (true) { account.withdraw((int) (Math.random() * 10) + 1); } } } private static class Account { private static Lock lock = new ReentrantLock(); private static Condition newDeposite = lock.newCondition(); private int balance = 0; public int getBalance() { return this.balance; } public void withdraw(int amount) { lock.lock(); try { while (this.balance < amount) { newDeposite.await(); //super.wait(); } balance -= amount; System.out.println("ttwithdraw " + amount + "tt" + getBalance()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { lock.unlock(); } } public void deposite(int amount) { lock.lock(); try { balance += amount; System.out.println("deposite:" + amount + "tttt" + getBalance()); newDeposite.signal(); //super.notifyAll(); } catch (Exception ex) { ex.printStackTrace(); } finally { lock.unlock(); } } } } 第二種是synchronized加object物件中的wait和notify方法: package com.ccy.test; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadCooperation2 { private static Account account = new Account(); public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(2); executor.execute(new DepositeTask()); executor.execute(new WithdrawTask()); executor.shutdown(); System.out.println("Thread 1ttThread2ttBalance"); } private static class DepositeTask implements Runnable { @Override public void run() { // TODO Auto-generated method stub try { while (true) { account.deposite((int) (Math.random() * 10) + 1); Thread.sleep(1000); } } catch (Exception ex) { ex.printStackTrace(); } } } private static class WithdrawTask implements Runnable { @Override public void run() { // TODO Auto-generated method stub while (true) { account.withdraw((int) (Math.random() * 10) + 1); } } } private static class Account { // private static Lock lock = new ReentrantLock(); // // private static Condition newDeposite = lock.newCondition(); private int balance = 0; public int getBalance() { return this.balance; } public synchronized void withdraw(int amount) { // lock.lock(); try { while (this.balance < amount) { // newDeposite.await(); super.wait(); } balance -= amount; System.out.println("ttwithdraw " + amount + "tt" + getBalance()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } finally { // lock.unlock(); } } public synchronized void deposite(int amount) { // lock.lock(); try { balance += amount; System.out.println("deposite:" + amount + "tttt" + getBalance()); // newDeposite.signalAll(); super.notify(); } catch (Exception ex) { ex.printStackTrace(); } finally { // lock.unlock(); } } } }