多線程練習一:銀行有一個賬戶,有兩個儲戶分別向同一個賬戶存3000元,每次存1000,存三次,每次存完打印賬戶餘額(兩個儲戶儘量交替存)

多線程練習一:銀行有一個賬戶,有兩個儲戶分別向同一個賬戶存3000元,每次存1000,存三次,每次存完打印賬戶餘額(兩個儲戶交替存)

​ 對於本題,需要有賬戶(Account)、儲戶(User)、以及一個測試類(AccountTset)

​ 可以分別用繼承Thread類和實現Runnable接口的方式來解決,同時需要注意線程同步的安全問題。

​ 說明:用戶User需要共享一個賬戶Account,這時需要在User類中添加一個Account類型的屬性,以及爲User類提供Account有參構造,以調用其存錢方法,同時在測試類中也可保證不管new 多少個User都是共享同一個Account。

1.繼承Thread類的方法:

class Account {
   
   
    //賬戶餘額爲money
    private double money;
	//有參構造器
    public Account(double money) {
   
   
        this.money = money;
    }
	//存錢方法
    public void cunqian(double jine) {
   
   
        if (jine > 0) {
   
   
          	//用同步代碼塊的方式解決線程安全問題,同步監視器爲Account.class
            synchronized (Account.class) {
   
   
            	Account.class.notify();
                money += 1000;
              
                try {
   
   
                    Thread.sleep(100);
                } catch (InterruptedException e) {
   
   
                    e.printStackTrace();
                }
              
                System.out.println(Thread.currentThread().getName() + "-存款,賬戶餘額爲:" + money);
                //
                try {
   
   
                    Account.class.wait();
                } catch (InterruptedException e) {
   
   
                    e.printStackTrace();
                }
            }
        }
    }
}

class User extends Thread {
   
   
    private Account account;
	//有參構造器
    public User(Account account) {
   
   
        this.account = account;
    }
    //重寫run方法
    @Override
    public void run() {
   
   
        for (int i = 0; i < 3; i++) {
   
   
            account.cunqian(1000);
        }
    }
}


public class AccountTest {
   
   
    public static void main(String[] args) {
   
   
        Account acc = new Account(0);
		//創建兩個User對象 (兩個線程)
        User u1 = new User(acc);
        User u2 = new User(acc);
		//爲兩個對象(線程)命名
        u1.setName("甲");
        u2.setName("乙");

        u1.start();
        u2.start();
    }
}

2.實現Runnable接口:

​ 說明: ReentrantLock lock = new ReentrantLock(true);在公平鎖(參數爲true)中,線程執行完會讓出cpu執行權給下一個排隊的線程。而非公平鎖(參數爲false或五參數)對鎖的獲取是亂序的。

class Account {
   
   
    private double money;
	實例化ReentrantLock,公平鎖
    ReentrantLock lock = new ReentrantLock(true);

    public Account(double money) {
   
   
        this.money = money;
    }

    public void cunqian(double jine) {
   
   
        if (jine > 0) {
   
   
            lock.lock();
            money += jine;
            try {
   
   
                Thread.sleep(100);
            } catch (InterruptedException e) {
   
   
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "-存款,賬戶餘額爲:" + money);
        }
        lock.unlock();
    }
}


class User implements Runnable {
   
   
    private Account account;

    public User(Account account) {
   
   
        this.account = account;
    }

    @Override
    public void run() {
   
   
        for (int i = 0; i < 3; i++) {
   
   
            account.cunqian(1000);
        }
    }
}

public class AccountTest {
   
   
    public static void main(String[] args) {
   
   
        Account acc = new Account(0);
        User user = new User(acc);

        Thread t1 = new Thread(user);
        Thread t2 = new Thread(user);

        t1.setName("甲");
        t2.setName("乙");

        t1.start();
        t2.start();
    }
}

趙大海看完能不能發把ju?

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