中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

標題優(yōu)化方法百度網(wǎng)站免費優(yōu)化軟件下載

標題優(yōu)化方法,百度網(wǎng)站免費優(yōu)化軟件下載,手表在哪個平臺買正品,注冊域名需要多久同步是什么? 當兩個線程同時對一個變量進行修改時,不同的訪問順序會造成不一樣的結(jié)果,這時候就需要同步保證結(jié)果的唯一性。 未同步時 新建Bank類,transfer()用于在兩個賬戶之間轉(zhuǎn)賬金額 class Bank {private double[] account…

同步是什么?

當兩個線程同時對一個變量進行修改時,不同的訪問順序會造成不一樣的結(jié)果,這時候就需要同步保證結(jié)果的唯一性。

未同步時

新建Bank類,transfer()用于在兩個賬戶之間轉(zhuǎn)賬金額

class Bank {private double[] accounts;public Bank(int accountNum, double initialMoney) {accounts = new double[accountNum];Arrays.fill(accounts, initialMoney);}public void transfer(int from, int to, double money) {if (accounts[from] < money) {return;}System.out.print(Thread.currentThread());accounts[from] -= money;System.out.printf("%10.2f from %d to %d", money, from, to);accounts[to] += money;System.out.printf(" Total %10.2f%n", getTotal());}public double getTotal() {double total = 0.0d;for (double temp : accounts) {total += temp;}return total;}public int size() {return accounts.length;}
}

假設銀行有1000個開戶人,每個人賬戶有1000元,新建1000個線程進行隨機轉(zhuǎn)賬,無論怎么轉(zhuǎn)賬,總金額都應該為1000000,但實際的錢卻越來越少(這個例子不太好,原因是浮點數(shù)加減可能誤差)

int NACCOUNTS = 1000;
double INITIAL_BALANCE = 1000;
double MAX_AMOUNT = 1000;
int DELAY = 10;Bank bank = new Bank(NACCOUNTS, INITIAL_BALANCE);
for (int i = 0; i < NACCOUNTS; i++) {int fromAccount = i;new Thread(new Runnable() {@Overridepublic void run() {try {while (true) {int toAccount = (int) (bank.size() * Math.random());double money = MAX_AMOUNT * Math.random();bank.transfer(fromAccount, toAccount, money);Thread.sleep((int) (DELAY * Math.random()));}} catch (InterruptedException e) {e.printStackTrace();}}}).start();
}

原因分析:

  • 當兩個線程同時執(zhí)行到accounts[to] += money;
  • 線程1取出accounts[to](如900)放到寄存器,+money(如100),正準備寫回accounts[to](變成了1000)時
  • 線程2搶占到權限執(zhí)行accounts[to] += money 將accounts[to]修改為了10002
  • 線程1再寫就將10002覆蓋成了1000

ReentrantLock

修改Bank,對其transfer方法加鎖,注意lock應該為成員變量,即每個Bank實例都只有一把鎖,不同對象之間的鎖不會互相影響,需要在finally釋放鎖

class Bank {private double[] accounts;private ReentrantLock lock = new ReentrantLock();public Bank(int accountNum, double initialMoney) {accounts = new double[accountNum];Arrays.fill(accounts, initialMoney);}public void transfer(int from, int to, double money) {if (accounts[from] < money) {return;}lock.lock();try {System.out.print(Thread.currentThread());accounts[from] -= money;System.out.printf("%10.2f from %d to %d", money, from, to);accounts[to] += money;System.out.printf(" Total %10.2f%n", getTotal());} finally {lock.unlock();}}public double getTotal() {double total = 0.0d;for (double temp : accounts) {total += temp;}return total;}public int size() {return accounts.length;}
}

Condition

在轉(zhuǎn)賬時,應該避免選擇沒有足夠資金的賬號轉(zhuǎn)出

if(bank.getMoney(fromAccount) >= money){bank.transfer(fromAccount, toAccount, money);
}

但在多線程情況下,可能兩個線程同時進入if,一個線程轉(zhuǎn)賬后導致另外一個線程金額不夠轉(zhuǎn)賬,故我們要確保在檢查之后加鎖禁止別的線程先行一步

private ReentrantLock lock = new ReentrantLock();
lock.lock();
try {while(account[from]  < money){}
}finally{lock.unlock();
}

但當賬戶沒有錢的時候,轉(zhuǎn)出線程會一直等待其他線程轉(zhuǎn)入資金,而其他線程因為無法拿到鎖而無法轉(zhuǎn)入,這就造成了死鎖,這時候就需要條件對象,當金額不足時阻塞線程放棄鎖的持有

private ReentrantLock lock = new ReentrantLock();
private Condition moneyEnough;lock.lock();
try {moneyEnough = lock.newCondition();while(account[from]  < money){moneyEnough.await();}
}finally{lock.unlock();
}

當其他線程轉(zhuǎn)賬后,應該調(diào)用signalAll()喚起所有await()中的線程,當其中的某個線程被調(diào)度并再次獲取鎖后,會再進入try子句檢測金額是否足夠

moneyEnough.signalAll();

Tips:

  • 還有一個signal()方法隨機喚起一個等待線程
  • 當所有線程的金額都小于轉(zhuǎn)賬金額,調(diào)用await(),所有線程都會阻塞,此時會再次死鎖

synchronized

Java中每一個對象都有一個內(nèi)部鎖,如果一個方法用synchronized聲明,線程調(diào)用該方法時需要獲得其內(nèi)部鎖,即

public synchronized void method(){}

等價于

private ReentrantLock innerLock = new ReentrantLock();
public void method(){innerLock.lock();try{}finally{innerLock.unlock();}
}

內(nèi)部鎖只有一個條件,對其的阻塞和喚醒調(diào)用wait()、notifyAll()/notify(),它們是Object中的final方法,相當對ReentrantLock調(diào)用

innerLock.await();
innerLock.signalAll();

將靜態(tài)方法聲明為synchronized,調(diào)用該方法時會鎖住對應的類,此時其他線程無法調(diào)用該類的其他同步靜態(tài)方法

Tips:

  • 內(nèi)部鎖不能中斷一個正在試圖獲得鎖的線程
  • 鎖時不能設置超時
  • 只有一個條件

該使用哪種鎖機制?

使用synchronized可減少代碼的編寫,減少出錯的幾率

使用ReentrantLock+Condition可以自行控制鎖的過程,實現(xiàn)多個條件

同步阻塞

使用其他對象的鎖來完成原子操作

public class bank{private Object lock = new Object();public void transfer(int from, int to, double money) {synchronized(lock){}}
}

監(jiān)視器

volatile

若如果只有一兩個域可能發(fā)生多線程的誤寫,可對該域聲明為volatile,虛擬機和編譯器就知道該域是可能被另一個線程并發(fā)更新的,但其不能保證原子性

boolean flag;
public void Not(){flag = !flag;
}

如上,不能保證其再讀取、翻轉(zhuǎn)和寫入時不被中斷

final和鎖

當把域聲明為final時,其他線程對其的讀取只能是構造成功后的值,而不會是null

fial Map<String, Double> accounts = new HashMap<>();

原子性

死鎖

線程局部變量

當多個線程都要調(diào)用Random中的方法生成隨機數(shù)時,由于Random是加鎖的,其他線程就得等待,此時可用TheadLocal輔助類為各個線程提供各自的Random實例

ThreadLocal<Random> threadLocal = ThreadLocal.withInitial(() -> new Random());
threadLocal.get().nextInt();

此外,專門創(chuàng)建多線程隨機數(shù)的ThreadLocalRandom,其current()方法會返回當前線程的Random類實例

ThreadLocalRandom.current().nextInt();

鎖超時

當線程調(diào)用tryLock()方法去申請另一個線程的鎖時,很有可能發(fā)生阻塞,故可在申請時設置時長

private ReentrantLock lock = new ReentrantLock();
try {lock.tryLock(100, TimeUnit.SECONDS);
} catch (InterruptedException e) {e.printStackTrace();
}

讀寫鎖

讀寫鎖可從ReentrantReadWriteLock取出,為所有獲取方法加上讀鎖,為所有修改方法加上寫鎖

ReentrantReadWriteLock reentrantReadWriteLock = new ReentrantReadWriteLock();
Lock readLock = reentrantReadWriteLock.readLock();
Lock writeLock = reentrantReadWriteLock.writeLock();

為什么棄用stop()和suspend()

stop()方法用來終止線程,并立即釋放線程所獲得的鎖,這會導致對象狀態(tài)不一致(如錢已被轉(zhuǎn)出,但在轉(zhuǎn)入前stop,會導致數(shù)據(jù)丟失)

故無法確定什么時候調(diào)用stop()是安全的,在希望停止線程的時候應該中斷線程,被中斷的線程會在安全的時候停止

suspend()方法用來阻塞線程,直至另一個線程調(diào)用resume(),當用suspend()掛起一個持有一個鎖的線程,則該鎖在resume()之前是不可用的。

若此時再用suspend()方法的線程獲取該鎖,則會死鎖,被掛起的鎖等待resume()釋放,而要resume()則要獲取被掛起的鎖

http://www.risenshineclean.com/news/48351.html

相關文章:

  • php企業(yè)網(wǎng)站源代碼網(wǎng)站優(yōu)化方式有哪些
  • 網(wǎng)站開發(fā)論文題目seo排名系統(tǒng)源碼
  • 網(wǎng)站的ci設計怎么做優(yōu)化網(wǎng)站打開速度
  • 網(wǎng)站開發(fā) 外包空心cba最新排名
  • javaweb一個旅游網(wǎng)站怎么做無憂軟文網(wǎng)
  • 新聞網(wǎng)站個人可以做嗎軟文寫作范例大全
  • wordpress插件分享顯示官網(wǎng)seo關鍵詞排名系統(tǒng)
  • 南平網(wǎng)站建設公司超能搜索引擎系統(tǒng)網(wǎng)站
  • 網(wǎng)站建設教學廊坊電商網(wǎng)站入口
  • 二維碼圖片個人網(wǎng)站seo入門
  • 寶坻做網(wǎng)站上海關鍵詞優(yōu)化排名哪家好
  • wordpress無法新建頁面網(wǎng)站優(yōu)化+山東
  • 中國做爰網(wǎng)站外鏈工具軟件
  • web軟件開發(fā)工具百度seo插件
  • 廣州建委網(wǎng)站google推廣一年的費用
  • 網(wǎng)站建設經(jīng)典范例萬網(wǎng)域名注冊查詢網(wǎng)
  • 格爾木有做網(wǎng)站的嗎seo網(wǎng)站推廣杭州
  • 行業(yè)軟件公司外包南京seo全網(wǎng)營銷
  • div css3網(wǎng)站布局鄭州制作網(wǎng)站公司
  • 網(wǎng)站建設進度表怎么做看廣告收益最高的軟件
  • 國際新聞最新消息戰(zhàn)爭視頻網(wǎng)站關鍵字排名優(yōu)化
  • 百度云盤做網(wǎng)站百度新聞客戶端
  • 動態(tài)網(wǎng)站開發(fā)報告seo推廣優(yōu)化
  • 網(wǎng)站建設app平臺關鍵詞排名優(yōu)化
  • 網(wǎng)站建設公司怎么宣傳廈門百度seo
  • 重慶第一門戶網(wǎng)站附子seo教程
  • 重慶論壇網(wǎng)站建設企業(yè)營銷策劃
  • wordpress綁定百家號鼓樓網(wǎng)頁seo搜索引擎優(yōu)化
  • 網(wǎng)站開發(fā)工程師職業(yè)定位成品網(wǎng)站貨源1
  • 常平網(wǎng)站仿做網(wǎng)址大全瀏覽器下載