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

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

不用淘寶客api如何做網(wǎng)站網(wǎng)站制作 網(wǎng)站建設(shè)

不用淘寶客api如何做網(wǎng)站,網(wǎng)站制作 網(wǎng)站建設(shè),長(zhǎng)春企業(yè)網(wǎng)站排名優(yōu)化,建設(shè)網(wǎng)站草案一、為什么要線程同步 因?yàn)楫?dāng)我們有多個(gè)線程要同時(shí)訪問(wèn)一個(gè)變量或?qū)ο髸r(shí),如果這些線程中既有讀又有寫(xiě)操作時(shí),就會(huì)導(dǎo)致變量值或?qū)ο蟮臓顟B(tài)出現(xiàn)混亂,從而導(dǎo)致程序異常。舉個(gè)例子,如果一個(gè)銀行賬戶同時(shí)被兩個(gè)線程操作,一個(gè)…

一、為什么要線程同步

? ? ?因?yàn)楫?dāng)我們有多個(gè)線程要同時(shí)訪問(wèn)一個(gè)變量或?qū)ο髸r(shí),如果這些線程中既有讀又有寫(xiě)操作時(shí),就會(huì)導(dǎo)致變量值或?qū)ο蟮臓顟B(tài)出現(xiàn)混亂,從而導(dǎo)致程序異常。舉個(gè)例子,如果一個(gè)銀行賬戶同時(shí)被兩個(gè)線程操作,一個(gè)取100塊,一個(gè)存錢100塊。假設(shè)賬戶原本有0塊,如果取錢線程和存錢線程同時(shí)發(fā)生,會(huì)出現(xiàn)什么結(jié)果呢?取錢不成功,賬戶余額是100.取錢成功了,賬戶余額是0.那到底是哪個(gè)呢?很難說(shuō)清楚。因此多線程同步就是要解決這個(gè)問(wèn)題。

二、不同步時(shí)的代碼

Bank.java

復(fù)制代碼
package threadTest;  /** * @author lixiaoxi * */  
public class Bank {  private int count =0;//賬戶余額  //存錢  public  void addMoney(int money){  count +=money;  System.out.println(System.currentTimeMillis()+"存進(jìn):"+money);  }  //取錢  public  void subMoney(int money){  if(count-money < 0){  System.out.println("余額不足");  return;  }  count -=money;  System.out.println(+System.currentTimeMillis()+"取出:"+money);  }  //查詢  public void lookMoney(){  System.out.println("賬戶余額:"+count);  }  
}
復(fù)制代碼

SyncThreadTest.java

復(fù)制代碼
package threadTest;  public class SyncThreadTest {  public static void main(String args[]){  final Bank bank=new Bank();  Thread tadd=new Thread(new Runnable() {  @Override  public void run() {  // TODO Auto-generated method stub  while(true){  try {  Thread.sleep(1000);  } catch (InterruptedException e) {  // TODO Auto-generated catch block  
                        e.printStackTrace();  }  bank.addMoney(100);  bank.lookMoney();  System.out.println("\n");  }  }  });  Thread tsub = new Thread(new Runnable() {  @Override  public void run() {  // TODO Auto-generated method stub  while(true){  bank.subMoney(100);  bank.lookMoney();  System.out.println("\n");  try {  Thread.sleep(1000);  } catch (InterruptedException e) {  // TODO Auto-generated catch block  
                        e.printStackTrace();  }     }  }  });  tsub.start();  tadd.start();  }  }
復(fù)制代碼

代碼很簡(jiǎn)單,我就不解釋了,看看運(yùn)行結(jié)果怎樣呢?截取了其中的一部分,是不是很亂,有些看不懂。

復(fù)制代碼
余額不足  
賬戶余額:0  余額不足  
賬戶余額:100  1441790503354存進(jìn):100  
賬戶余額:100  1441790504354存進(jìn):100  
賬戶余額:100  1441790504354取出:100  
賬戶余額:100  1441790505355存進(jìn):100  
賬戶余額:100  1441790505355取出:100  
賬戶余額:100
復(fù)制代碼

三、使用同步時(shí)的代碼

1、同步方法

即有synchronized關(guān)鍵字修飾的方法。?由于java的每個(gè)對(duì)象都有一個(gè)內(nèi)置鎖,當(dāng)用此關(guān)鍵字修飾方法時(shí),內(nèi)置鎖會(huì)保護(hù)整個(gè)方法。在調(diào)用該方法前,需要獲得內(nèi)置鎖,否則就處于阻塞狀態(tài)。

修改后的Bank.java

復(fù)制代碼
/** * @author lixiaoxi* */  
public class Bank {  private int count =0;//賬戶余額  //存錢  public  synchronized void addMoney(int money){  count +=money;  System.out.println(System.currentTimeMillis()+"存進(jìn):"+money);  }  //取錢  public  synchronized void subMoney(int money){  if(count-money < 0){  System.out.println("余額不足");  return;  }  count -=money;  System.out.println(+System.currentTimeMillis()+"取出:"+money);  }  //查詢  public void lookMoney(){  System.out.println("賬戶余額:"+count);  }  
}
復(fù)制代碼

再看看運(yùn)行結(jié)果:

復(fù)制代碼
余額不足  
賬戶余額:0  余額不足  
賬戶余額:0  1441790837380存進(jìn):100  
賬戶余額:100  1441790838380取出:100  
賬戶余額:0  1441790838380存進(jìn):100  
賬戶余額:100  1441790839381取出:100  
賬戶余額:0
復(fù)制代碼

瞬間感覺(jué)可以理解了吧。

注: synchronized關(guān)鍵字也可以修飾靜態(tài)方法,此時(shí)如果調(diào)用該靜態(tài)方法,將會(huì)鎖住整個(gè)類。

2、同步代碼塊

即有synchronized關(guān)鍵字修飾的語(yǔ)句塊。被該關(guān)鍵字修飾的語(yǔ)句塊會(huì)自動(dòng)被加上內(nèi)置鎖,從而實(shí)現(xiàn)同步。

Bank.java代碼如下:

復(fù)制代碼
package threadTest;  package threadTest;  /** * @author lixiaoxi * */  
public class Bank {  private int count =0;//賬戶余額  //存錢  public void addMoney(int money){  synchronized (this) {  count +=money;  }  System.out.println(System.currentTimeMillis()+"存進(jìn):"+money);  }  //取錢  public void subMoney(int money){  synchronized (this) {  if(count-money < 0){  System.out.println("余額不足");  return;  }  count -=money;  }  System.out.println(+System.currentTimeMillis()+"取出:"+money);  }  //查詢  public void lookMoney(){  System.out.println("賬戶余額:"+count);  }  
}
復(fù)制代碼

運(yùn)行結(jié)果如下:

復(fù)制代碼
余額不足  
賬戶余額:0  1441791806699存進(jìn):100  
賬戶余額:100  1441791806700取出:100  
賬戶余額:0  1441791807699存進(jìn):100  
賬戶余額:100
復(fù)制代碼

效果和方法一差不多。

注:同步是一種高開(kāi)銷的操作,因此應(yīng)該盡量減少同步的內(nèi)容。通常沒(méi)有必要同步整個(gè)方法,使用synchronized代碼塊同步關(guān)鍵代碼即可。

3、使用特殊域變量(volatile)實(shí)現(xiàn)線程同步

(1)volatile關(guān)鍵字為域變量的訪問(wèn)提供了一種免鎖機(jī)制;

(2)使用volatile修飾域相當(dāng)于告訴虛擬機(jī)該域可能會(huì)被其他線程更新;

(3)因此每次使用該域就要重新計(jì)算,而不是使用寄存器中的值;

(4)volatile不會(huì)提供任何原子操作,它也不能用來(lái)修飾final類型的變量。

Bank.java代碼如下:

復(fù)制代碼
package threadTest;  /** * @author lixiaoxi * */  
public class Bank {  private volatile int count = 0;// 賬戶余額  // 存錢  public void addMoney(int money) {  count += money;  System.out.println(System.currentTimeMillis() + "存進(jìn):" + money);  }  // 取錢  public void subMoney(int money) {  if (count - money < 0) {  System.out.println("余額不足");  return;  }  count -= money;  System.out.println(+System.currentTimeMillis() + "取出:" + money);  }  // 查詢  public void lookMoney() {  System.out.println("賬戶余額:" + count);  }  
}
復(fù)制代碼

運(yùn)行效果怎樣呢?

復(fù)制代碼
余額不足  
賬戶余額:0  余額不足  
賬戶余額:100  1441792010959存進(jìn):100  
賬戶余額:100  1441792011960取出:100  
賬戶余額:0  1441792011961存進(jìn):100  
賬戶余額:100
復(fù)制代碼

是不是又看不懂了,又亂了。這是為什么呢?就是因?yàn)?span style="background-color:rgb(255,255,0);">volatile不能保證原子操作導(dǎo)致的,因此volatile不能代替synchronized。此外volatile會(huì)組織編譯器對(duì)代碼優(yōu)化,因此能不使用它就不使用它吧。它的原理是每次要線程要訪問(wèn)volatile修飾的變量時(shí)都是從內(nèi)存中讀取,而不是從緩存當(dāng)中讀取,因此每個(gè)線程訪問(wèn)到的變量值都是一樣的。這樣就保證了同步。

?4、使用重入鎖實(shí)現(xiàn)線程同步

在JavaSE5.0中新增了一個(gè)java.util.concurrent包來(lái)支持同步。ReentrantLock類是可重入、互斥、實(shí)現(xiàn)了Lock接口的鎖,?它與使用synchronized方法和塊具有相同的基本行為和語(yǔ)義,并且擴(kuò)展了其能力。
ReenreantLock類的常用方法有:
ReentrantLock() :創(chuàng)建一個(gè)ReentrantLock實(shí)例
lock() :獲得鎖
unlock() :釋放鎖
注:ReentrantLock()還有一個(gè)可以創(chuàng)建公平鎖的構(gòu)造方法,但由于能大幅度降低程序運(yùn)行效率,不推薦使用。

Bank.java代碼修改如下:

復(fù)制代碼
package threadTest;  import java.util.concurrent.locks.Lock;  
import java.util.concurrent.locks.ReentrantLock;  /** * @author lixiaoxi * */  
public class Bank {  private  int count = 0;// 賬戶余額  //需要聲明這個(gè)鎖  private Lock lock = new ReentrantLock();  // 存錢  public void addMoney(int money) {  lock.lock();//上鎖  try{  count += money;  System.out.println(System.currentTimeMillis() + "存進(jìn):" + money);  }finally{  lock.unlock();//解鎖  
        }  }  // 取錢  public void subMoney(int money) {  lock.lock();  try{  if (count - money < 0) {  System.out.println("余額不足");  return;  }  count -= money;  System.out.println(+System.currentTimeMillis() + "取出:" + money);  }finally{  lock.unlock();  }  }  // 查詢  public void lookMoney() {  System.out.println("賬戶余額:" + count);  }  
}
復(fù)制代碼

運(yùn)行效果怎樣呢?

復(fù)制代碼
余額不足  
賬戶余額:0  余額不足  
賬戶余額:0  1441792891934存進(jìn):100  
賬戶余額:100  1441792892935存進(jìn):100  
賬戶余額:200  1441792892954取出:100  
賬戶余額:100
復(fù)制代碼

效果和前兩種方法差不多。

? ? ?如果synchronized關(guān)鍵字能滿足用戶的需求,就用synchronized,因?yàn)樗芎?jiǎn)化代碼 。如果需要更高級(jí)的功能,就用ReentrantLock類,此時(shí)要注意及時(shí)釋放鎖,否則會(huì)出現(xiàn)死鎖,通常在finally代碼釋放鎖。

5、使用局部變量實(shí)現(xiàn)線程同步

Bank.java代碼如下:

復(fù)制代碼
package com.demo.test;/** * @author lixiaoxi* */ 
public class Bank {private static ThreadLocal<Integer> count = new ThreadLocal<Integer>(){  @Override  protected Integer initialValue() {  // TODO Auto-generated method stub  return 0;  }  };  // 存錢  public void addMoney(int money) {  count.set(count.get()+money);  System.out.println(System.currentTimeMillis() + "存進(jìn):" + money);  }  // 取錢  public void subMoney(int money) {  if (count.get() - money < 0) {  System.out.println("余額不足");  return;  }  count.set(count.get()- money);  System.out.println(+System.currentTimeMillis() + "取出:" + money);  }  // 查詢  public void lookMoney() {  System.out.println("賬戶余額:" + count.get());  }      
}
復(fù)制代碼

運(yùn)行效果:

復(fù)制代碼
余額不足
賬戶余額:01511166594460存進(jìn):100
賬戶余額:200余額不足
賬戶余額:01511166595460存進(jìn):100
賬戶余額:300余額不足
賬戶余額:01511166596460存進(jìn):100
賬戶余額:400
復(fù)制代碼

看了運(yùn)行效果,一開(kāi)始一頭霧水,怎么只讓存,不讓取啊?看看ThreadLocal的原理:

? ? ?如果使用ThreadLocal管理變量,則每一個(gè)使用該變量的線程都獲得該變量的副本,副本之間相互獨(dú)立,這樣每一個(gè)線程都可以隨意修改自己的變量副本,而不會(huì)對(duì)其他線程產(chǎn)生影響。現(xiàn)在明白了吧,原來(lái)每個(gè)線程運(yùn)行的都是一個(gè)副本,也就是說(shuō)存錢和取錢是兩個(gè)賬戶,只是名字相同而已。所以就會(huì)發(fā)生上面的效果。

ThreadLocal與同步機(jī)制

a.ThreadLocal與同步機(jī)制都是為了解決多線程中相同變量的訪問(wèn)沖突問(wèn)題;

b.前者采用以”空間換時(shí)間”的方法,后者采用以”時(shí)間換空間”的方式。

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

相關(guān)文章:

  • 銀川做企業(yè)網(wǎng)站合肥seo報(bào)價(jià)
  • 重慶網(wǎng)站建設(shè)設(shè)計(jì)網(wǎng)絡(luò)營(yíng)銷十大成功案例
  • 娛樂(lè)網(wǎng)站開(kāi)發(fā)福州外包seo公司
  • 榮耀手機(jī)商城官方網(wǎng)站入口西安seo排名外包
  • 蘇州網(wǎng)站建設(shè)的一般流程職業(yè)技能培訓(xùn)網(wǎng)
  • 哪家做網(wǎng)站靠譜企業(yè)營(yíng)銷策劃
  • 福清網(wǎng)站建設(shè)百度收錄批量提交入口
  • 海門做網(wǎng)站自動(dòng)優(yōu)化句子的軟件
  • 數(shù)據(jù)分析師簡(jiǎn)歷襄陽(yáng)網(wǎng)站推廣優(yōu)化技巧
  • 北京住房城鄉(xiāng)建設(shè)部網(wǎng)站八大員千萬(wàn)不要去電商公司上班
  • 可以在哪些網(wǎng)站做翻譯兼職建立企業(yè)網(wǎng)站步驟
  • 天津平臺(tái)網(wǎng)站建設(shè)推薦廣告營(yíng)銷平臺(tái)
  • 成都旅游景點(diǎn)攻略自由行攻略關(guān)鍵詞優(yōu)化seo公司
  • 西安微網(wǎng)站建設(shè)百度一下 你就知道官網(wǎng)
  • 網(wǎng)站開(kāi)發(fā)需要考什么證網(wǎng)絡(luò)營(yíng)銷渠道有哪三類
  • 南陽(yáng)做網(wǎng)站的公怎樣進(jìn)行網(wǎng)絡(luò)營(yíng)銷吸引顧客
  • 商標(biāo)被注冊(cè)了做網(wǎng)站國(guó)外網(wǎng)站推廣公司
  • 建筑工程外架安全網(wǎng)西安的網(wǎng)絡(luò)優(yōu)化公司
  • 做算法題的 網(wǎng)站成品網(wǎng)站貨源1
  • 網(wǎng)站建設(shè)策劃實(shí)訓(xùn)總結(jié)友情鏈接怎么連
  • 遵義新藍(lán)外國(guó)語(yǔ)學(xué)校網(wǎng)站建設(shè)臺(tái)州seo優(yōu)化
  • 郴州北湖區(qū)疫情最新消息網(wǎng)站優(yōu)化
  • 建設(shè)企業(yè)網(wǎng)站進(jìn)去無(wú)法顯示怎么在百度上免費(fèi)做廣告
  • 如何通過(guò)做網(wǎng)站月入上萬(wàn)廣州seo公司品牌
  • 溫州建設(shè)網(wǎng)站百度上??偛?/a>
  • 天津企商網(wǎng)站建設(shè)公司關(guān)鍵詞優(yōu)化按天計(jì)費(fèi)
  • 網(wǎng)站如何做銀聯(lián)在線支付大連中小企業(yè)網(wǎng)絡(luò)營(yíng)銷
  • 一般做外貿(mào)上什么網(wǎng)站熱狗網(wǎng)站排名優(yōu)化外包
  • 建設(shè)網(wǎng)站com艾滋病阻斷藥
  • 網(wǎng)站robots.txt檢測(cè)網(wǎng)站關(guān)鍵詞在線優(yōu)化