多线程三种同步方式(模拟银行取款)
生活随笔
收集整理的這篇文章主要介紹了
多线程三种同步方式(模拟银行取款)
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
方法一:同步代碼塊
Accoun
package com.bjsxt.synch1;/*** 銀行賬戶類*/ public class Account {private int balance = 600;//余額/*** 取款* @param money*/public void withDraw(int money){this.balance = this.balance -money;}/*** 查看余額* @return*/public int getBalance(){return balance;} }取款線程
package com.bjsxt.synch1;/*** 取款的線程** 線程同步方式1:同步代碼塊** 總結1:認識同步監視器(鎖子)* ? synchronized(同步監視器){ }* 1)必須是引用數據類型,不能是基本數據類型* 2)在同步代碼塊中可以改變同步監視器對象的值,不能改變其引用* 3)盡量不要String和包裝類Integer做同步監視器.如果使用了,只要保證代碼塊中不對其進行任何操作也沒有關系* 4)一般使用共享資源做同步監視器即可* 5)也可以創建一個專門的同步監視器,沒有任何業務含義* 6)建議使用final修飾同步監視器** 總結2:同步代碼塊的執行過程* 1)第一個線程來到同步代碼塊,發現同步監視器open狀態,需要close,然后執行其中的代碼* 2)第一個線程執行過程中,發生了線程切換(阻塞 就緒),第一個線程失去了cpu,但是沒有開鎖open* 3)第二個線程獲取了cpu,來到了同步代碼塊,發現同步監視器close狀態,無法執行其中的代碼,第二個線程也進入阻塞狀態* 4)第一個線程再次獲取CPU,接著執行后續的代碼;同步代碼塊執行完畢,釋放鎖open* 5)第二個線程也再次獲取cpu,來到了同步代碼塊,發現同步監視器open狀態,重復第一個線程的處理過程(加鎖)* 強調:同步代碼塊中能發生線程切換嗎?能!!! 但是后續的被執行的線程也無法執行同步代碼塊(鎖仍舊close)* 總結3:線程同步 優點和缺點* ? 優點:安全* ? 缺點:效率低下 可能出現死鎖* ? * 總結4:其他* 1)多個代碼塊使用了同一個同步監視器(鎖),鎖住一個代碼塊的同時,也鎖住所有使用該鎖的所有代碼塊,其他線程無法訪問其中的任何一個代碼塊* 2)多個代碼塊使用了同一個同步監視器(鎖),鎖住一個代碼塊的同時,也鎖住所有使用該鎖的所有代碼塊, 但是沒有鎖住使用其他同步監視器的代碼塊,其他線程有機會訪問其他同步監視器的代碼塊*/ public class AccountRunnable implements Runnable{private final Account account = new Account();final Object obj = new Object();//byte [] buf = new byte[1];//final String str = "bjsxt";//final Integer in = 1234;//int n = 5;/*** 線程體:取款的步驟*/@Overridepublic void run() {//此處省略200句synchronized (account){if(account.getBalance()>=400){//余額足夠 臨界代碼try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//就取款account.withDraw(400);System.out.println(Thread.currentThread().getName()+"取款成功,當前余額:"+account.getBalance());}else{//余額不足//給出提示System.out.println(Thread.currentThread().getName()+"取款失敗,余額不足,當前余額:"+account.getBalance());}}//此處省略100句}public void method1(){synchronized (account){}}public void method2(){synchronized (obj){}}public void method3(){synchronized (obj){}} }main
package com.bjsxt.synch1;public class TestAccount {public static void main(String[] args) {//創建兩個線程,模擬兩個用戶Runnable runnable = new AccountRunnable();Thread thread1 = new Thread(runnable,"張三");Thread thread2 = new Thread(runnable,"張三妻子");//啟動兩個線程,模擬兩個用戶取款thread1.start();thread2.start();} }方法二:同步方法
銀行賬戶類
package com.bjsxt.synch2;/*** 銀行賬戶類*/ public class Account {private int balance = 600;//余額/*** 取款* @param money*/public void withDraw(int money){this.balance = this.balance -money;}/*** 查看余額* @return*/public int getBalance(){return balance;} }取款的線程
package com.bjsxt.synch2;/*** 取款的線程*方式2:同步方法** 1.不要給run()加鎖* 2. 非靜態同步方法的鎖:this* 靜態同步方法的鎖:類名.class* 3.同步方法和同步代碼塊哪種效率高* 同步代碼塊效率高**/ public class AccountRunnable implements Runnable{private Account account = new Account();/*** 線程體:取款的步驟*/@Overridepublic void run() {//此處省略200句//取款withDraw();//此處省略100句}public synchronized void withDraw(){ //非靜態同步方法的鎖是thisif(account.getBalance()>=400){ //余額足夠 臨界代碼try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//就取款account.withDraw(400);System.out.println(Thread.currentThread().getName()+"取款成功,當前余額:"+account.getBalance());}else{//余額不足//給出提示System.out.println(Thread.currentThread().getName()+"取款失敗,余額不足,當前余額:"+account.getBalance());}}public synchronized void method1(){ //this}public synchronized void method2(){ //this// Vector v;}public synchronized static void method3(){ //靜態的同步方法的鎖是類名.class 類對象 AccountRunnable.class//Class clazz = AccountRunnable.class;}public synchronized static void method4(){} }main
package com.bjsxt.synch2;public class TestAccount {public static void main(String[] args) {//創建兩個線程,模擬兩個用戶Runnable runnable = new AccountRunnable();Thread thread1 = new Thread(runnable,"張三");Thread thread2 = new Thread(runnable,"張三妻子");//啟動兩個線程,模擬兩個用戶取款thread1.start();thread2.start();} }方法三:鎖
銀行賬戶類
package com.bjsxt.synch3;/*** 銀行賬戶類*/ public class Account {private int balance = 600;//余額/*** 取款* @param money*/public void withDraw(int money){this.balance = this.balance -money;}/*** 查看余額* @return*/public int getBalance(){return balance;} }取款的線程
package com.bjsxt.synch3;import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;/*** 取款的線程*/ public class AccountRunnable implements Runnable{private Account account = new Account();//購買一把鎖private Lock lock = new ReentrantLock();//Re-entrant-Lock //entrance 可重入鎖/*** 線程體:取款的步驟*/@Overridepublic void run() {//此處省略200句//上鎖lock.lock();try{if(account.getBalance()>=400){//余額足夠 臨界代碼try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//就取款account.withDraw(400);System.out.println(Thread.currentThread().getName()+"取款成功,當前余額:"+account.getBalance());}else{//余額不足//給出提示System.out.println(Thread.currentThread().getName()+"取款失敗,余額不足,當前余額:"+account.getBalance());}method1();}finally{//解鎖lock.unlock();}//此處省略100句}public void method1(){lock.lock();try{method2();}finally{lock.unlock();}}public void method2(){lock.lock();try{}finally{lock.unlock();}} }main
package com.bjsxt.synch3;public class TestAccount {public static void main(String[] args) {//創建兩個線程,模擬兩個用戶Runnable runnable = new AccountRunnable();Thread thread1 = new Thread(runnable,"張三");Thread thread2 = new Thread(runnable,"張三妻子");//啟動兩個線程,模擬兩個用戶取款thread1.start();thread2.start();} }總結
以上是生活随笔為你收集整理的多线程三种同步方式(模拟银行取款)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: war thunder配置要求?
- 下一篇: 经济学专业实用什么电脑?