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

當(dāng)前位置: 首頁 > news >正文

標(biāo)題優(yōu)化方法南京谷歌seo

標(biāo)題優(yōu)化方法,南京谷歌seo,ps制作網(wǎng)頁實現(xiàn)頁面跳轉(zhuǎn),邯鄲做網(wǎng)站推廣的地方同步是什么? 當(dāng)兩個線程同時對一個變量進行修改時,不同的訪問順序會造成不一樣的結(jié)果,這時候就需要同步保證結(jié)果的唯一性。 未同步時 新建Bank類,transfer()用于在兩個賬戶之間轉(zhuǎn)賬金額 class Bank {private double[] account…

同步是什么?

當(dāng)兩個線程同時對一個變量進行修改時,不同的訪問順序會造成不一樣的結(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;}
}

假設(shè)銀行有1000個開戶人,每個人賬戶有1000元,新建1000個線程進行隨機轉(zhuǎn)賬,無論怎么轉(zhuǎn)賬,總金額都應(yīng)該為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();
}

原因分析:

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

ReentrantLock

修改Bank,對其transfer方法加鎖,注意lock應(yīng)該為成員變量,即每個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)賬時,應(yīng)該避免選擇沒有足夠資金的賬號轉(zhuǎn)出

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

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

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

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

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

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

moneyEnough.signalAll();

Tips:

  • 還有一個signal()方法隨機喚起一個等待線程
  • 當(dāng)所有線程的金額都小于轉(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方法,相當(dāng)對ReentrantLock調(diào)用

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

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

Tips:

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

該使用哪種鎖機制?

使用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和鎖

當(dāng)把域聲明為final時,其他線程對其的讀取只能是構(gòu)造成功后的值,而不會是null

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

原子性

死鎖

線程局部變量

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

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

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

ThreadLocalRandom.current().nextInt();

鎖超時

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

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

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

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

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

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

相關(guān)文章:

  • 電子商務(wù)網(wǎng)站建設(shè) iis怎樣做網(wǎng)站推廣
  • 蒲城做網(wǎng)站南昌seo排名優(yōu)化
  • 重慶九龍坡營銷型網(wǎng)站建設(shè)公司哪家好站長之家查詢
  • 網(wǎng)站源碼推薦sem競價是什么
  • 網(wǎng)站建設(shè)課本電腦零基礎(chǔ)培訓(xùn)學(xué)校
  • 解釋自己做的網(wǎng)站百度2019舊版本下載
  • 在線客服咨詢系統(tǒng)seo培訓(xùn)費用
  • 自助建站網(wǎng)站源碼第一站長網(wǎng)
  • 做搜狗網(wǎng)站點擊新聞稿代寫
  • html做動態(tài)網(wǎng)站嗎促銷活動推廣方案
  • 如何免費做網(wǎng)站個人永久免費自助建站
  • 網(wǎng)站建設(shè)域名杭州百度推廣電話
  • 網(wǎng)站頁面設(shè)計技術(shù)參數(shù)寧波seo推薦推廣渠道
  • 管理網(wǎng)站建設(shè)源代碼程序百度百家官網(wǎng)入口
  • 做網(wǎng)站的圖片從哪里找重慶seo排名電話
  • 《語文建設(shè)》網(wǎng)站網(wǎng)絡(luò)營銷策劃的基本原則是什么
  • 企業(yè)網(wǎng)站網(wǎng)址視頻seo優(yōu)化教程
  • 深圳提供網(wǎng)站建設(shè)服務(wù)平臺武漢網(wǎng)站維護公司
  • 信譽好的網(wǎng)站建設(shè)公司百度網(wǎng)盟推廣
  • 專業(yè)做制作網(wǎng)站天津推廣的平臺
  • 寧波建網(wǎng)站哪家好用點網(wǎng)站建設(shè)與管理屬于什么專業(yè)
  • 網(wǎng)絡(luò)公關(guān)公司是做啥的亞馬遜seo什么意思
  • 你的網(wǎng)站尚未進行備案網(wǎng)站推廣軟件免費
  • 做網(wǎng)站做一個什么主題的什么叫軟文
  • 給網(wǎng)站做壓力測試公關(guān)公司一般收費標(biāo)準(zhǔn)
  • 電商網(wǎng)站界面規(guī)范seo優(yōu)化標(biāo)題 關(guān)鍵詞
  • 如何做優(yōu)化網(wǎng)站排名網(wǎng)站關(guān)鍵詞優(yōu)化排名怎么做
  • 學(xué)做的網(wǎng)站基礎(chǔ)蛋糕線上推廣方案怎么做
  • 視頻下載網(wǎng)站軟件做副屏網(wǎng)絡(luò)營銷的宏觀環(huán)境
  • 教育行業(yè)怎么做網(wǎng)站投放吸引人氣的營銷方案