1. 程式人生 > >java多執行緒-簡單轉賬

java多執行緒-簡單轉賬

/**
 * Created by gmy on 2017/10/14.
 */
public class App {
    public static void main(String[] args) throws InterruptedException {
        final Runner runner=new Runner();
        Thread t1=new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    runner.firstThread();
                } catch
(InterruptedException e) { e.printStackTrace(); } } }); Thread t2 =new Thread(new Runnable() { @Override public void run() { try { runner.secondThread(); }catch
(InterruptedException ignored){ } } }); t1.start(); t2.start(); t1.join(); t2.join(); runner.finished(); } }
/**
 * Created by gmy on 2017/10/14.
 */
public class Runner {
    private Account account1=new Account();
    private
Account account2=new Account(); private Lock lock1=new ReentrantLock(); private Lock lock2=new ReentrantLock(); private void acquireLocks(Lock firstLock,Lock secondLock) throws InterruptedException{ while(true){ boolean gotFirstLock=false; boolean gotSecondLock=false; try { gotFirstLock=firstLock.tryLock();//tryLock是看這個鎖是否是可用的,沒有被其他執行緒佔用 gotSecondLock=secondLock.tryLock(); }finally { if(gotFirstLock&&gotSecondLock)return; else if (gotFirstLock)firstLock.unlock(); else if (gotSecondLock)secondLock.unlock(); } Thread.sleep(1); } } public void firstThread()throws InterruptedException{ Random random=new Random(); for (int i=0;i<10000;i++){ acquireLocks(lock1,lock2); try { Account.transfer(account1,account2,random.nextInt(100)); }finally { lock1.unlock(); lock2.unlock(); } } } public void secondThread()throws InterruptedException{ Random random=new Random(); for (int i=0;i<10000;i++){ acquireLocks(lock2,lock1); try { Account.transfer(account2,account1,random.nextInt(100)); }finally { lock1.unlock(); lock2.unlock(); } } } public void finished(){ System.out.println("Account 1 balance "+account1.getBalance()); System.out.println("Account 2 balance "+account2.getBalance()); System.out.println("Total balance"+(account2.getBalance()+account1.getBalance())); } }
public class Account {
    private int balance=10000;//底金
    public void deposit(int amount){//存錢
        balance+=amount;
    }
    public void withdraw(int amount){//取錢
        balance-=amount;
    }
    public int getBalance(){
        return balance;
    }
    public static void transfer(Account account1,Account account2,int amount){//轉賬
        account1.withdraw(amount);
        account2.deposit(amount);
    }
}

解析:

  1. thread.Join把指定的執行緒加入到當前執行緒。例如在main 執行緒中呼叫了t1.join()是指t1執行緒執行完畢