同步方法及同步代码块
生活随笔
收集整理的這篇文章主要介紹了
同步方法及同步代码块
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
synchronized方法和synchronized塊
synchronized方法必須獲得對象的鎖才能執(zhí)行,否則線程阻塞,方法一旦執(zhí)行,就獨(dú)占此鎖,直到方法返回才釋放鎖,后面被阻塞的線程才能獲得這個鎖,繼續(xù)執(zhí)行
synchronized會影響效率
同步塊synchronized(Obj){},Obj是同步監(jiān)聽器,第一個線程訪問,所定Obj,完后解鎖Obj,第二個才能訪問
同步方法弊端:方法里面需要修改的內(nèi)容才需要鎖,鎖的太多,浪費(fèi)資源
package com.wuming.syn.synch; //不安全的買票 public class UnSafeBuyTicket {public static void main(String[] args) {BuyTicket station = new BuyTicket();new Thread(station,"苦逼的我").start();new Thread(station,"牛逼的你們").start();new Thread(station,"可惡的黃牛黨").start();} }class BuyTicket implements Runnable{//票private int ticketNums=10;boolean flag=true;//停止方式/*** When an object implementing interface <code>Runnable</code> is used* to create a thread, starting the thread causes the object's* <code>run</code> method to be called in that separately executing* thread.* <p>* The general contract of the method <code>run</code> is that it may* take any action whatsoever.** @see Thread#run()*/@Overridepublic void run() {//買票while(flag){try {buy();} catch (InterruptedException e) {e.printStackTrace();}}}//synchronized同步方法,鎖的是this BuyTicketprivate synchronized void buy() throws InterruptedException {//判斷是否有票if (ticketNums<=0){flag=false;return;}//模擬延時Thread.sleep(100);//買票System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);//加了synchronized,安全/* 苦逼的我拿到10可惡的黃牛黨拿到9可惡的黃牛黨拿到8牛逼的你們拿到7可惡的黃牛黨拿到6苦逼的我拿到5苦逼的我拿到4可惡的黃牛黨拿到3牛逼的你們拿到2可惡的黃牛黨拿到1*/} }===============
package com.wuming.syn; //不安全的取錢 //兩個人去銀行取錢,賬戶 public class UnSafeBank {public static void main(String[] args) {//賬戶Account account = new Account(100,"結(jié)婚基金");Drawing you = new Drawing(account,50,"你");Drawing girlFriend = new Drawing(account,100,"girlFriend");you.start();girlFriend.start();}} //賬戶 class Account{int money;//余額String name;//卡名public Account(int money, String name) {this.money = money;this.name = name;} }//銀行,模擬取款 class Drawing extends Thread{Account account;//賬戶//取了多少錢int drawingMoney;//現(xiàn)在手里有多少錢int nowMoney;public Drawing(Account account, int drawingMoney, String name) {super(name);//線程namethis.account = account;this.drawingMoney = drawingMoney;this.nowMoney = nowMoney;} //取錢//synchronized默認(rèn)鎖的是本身@Overridepublic void run() {//鎖的對象是變化的量,增刪改;改成this就是指銀行,線程不安全如下/* 結(jié)婚基金余額為:-50結(jié)婚基金余額為:-50你手里的錢50girlFriend手里的錢100*/synchronized (account){//判斷有沒有錢if(account.money-drawingMoney<0){System.out.println(Thread.currentThread().getName()+"錢不夠,取不了");return;}//sleep可以放大問題的發(fā)生性try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//卡內(nèi)余額=余額-你取的錢account.money=account.money-drawingMoney;//你手里的錢nowMoney=nowMoney+drawingMoney;System.out.println(account.name+"余額為:"+account.money);//Thread.currentThread().getName()=this.getName();System.out.println(this.getName()+"手里的錢"+nowMoney);}//使用同步塊 synchronized (account),線程安全/* 結(jié)婚基金余額為:50你手里的錢50girlFriend錢不夠,取不了*/} }===============
package com.wuming.syn.synch;import java.util.ArrayList; import java.util.List;//線程不安全的集合 public class UnsafeList {public static void main(String[] args) {List<String> list=new ArrayList<String>();for (int i = 0; i < 10000; i++) {new Thread(()->{synchronized (list){//線程安全list.add(Thread.currentThread().getName());}}).start();}try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(list.size());//每次運(yùn)行都不夠10000,線程不安全,兩個線程同時操作同一個位置,//兩個數(shù)組添加到同一個位置,就會覆蓋掉,元素就會少} }10000
總結(jié)
以上是生活随笔為你收集整理的同步方法及同步代码块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Python format 函数- Py
- 下一篇: BugkuCTF-MISC题爆照