最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談Java并發(fā)編程之Lock鎖和條件變量

 更新時間:2020年08月03日 11:15:16   作者:蘭亭風(fēng)雨  
這篇文章主要介紹了淺談Java并發(fā)編程之Lock鎖和條件變量,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

簡單使用Lock鎖

    Java 5中引入了新的鎖機制——java.util.concurrent.locks中的顯式的互斥鎖:Lock接口,它提供了比synchronized更加廣泛的鎖定操作。Lock接口有3個實現(xiàn)它的類:ReentrantLock、ReetrantReadWriteLock.ReadLock和ReetrantReadWriteLock.WriteLock,即重入鎖、讀鎖和寫鎖。lock必須被顯式地創(chuàng)建、鎖定和釋放,為了可以使用更多的功能,一般用ReentrantLock為其實例化。為了保證鎖最終一定會被釋放(可能會有異常發(fā)生),要把互斥區(qū)放在try語句塊內(nèi),并在finally語句塊中釋放鎖,尤其當(dāng)有return語句時,return語句必須放在try字句中,以確保unlock()不會過早發(fā)生,從而將數(shù)據(jù)暴露給第二個任務(wù)。因此,采用lock加鎖和釋放鎖的一般形式如下:

  Lock lock = new ReentrantLock();//默認(rèn)使用非公平鎖,如果要使用公平鎖,需要傳入?yún)?shù)true
  ........
  lock.lock();
  try {
   //更新對象的狀態(tài)
   //捕獲異常,必要時恢復(fù)到原來的不變約束
  //如果有return語句,放在這里
 } finally {
   lock.unlock();  //鎖必須在finally塊中釋放
 }

ReetrankLock與synchronized比較

  性能比較

  在JDK1.5中,synchronized是性能低效的。因為這是一個重量級操作,它對性能最大的影響是阻塞的是實現(xiàn),掛起線程和恢復(fù)線程的操作都需要轉(zhuǎn)入內(nèi)核態(tài)中完成,這些操作給系統(tǒng)的并發(fā)性帶來了很大的壓力。相比之下使用Java提供的Lock對象,性能更高一些。Brian Goetz對這兩種鎖在JDK1.5、單核處理器及雙Xeon處理器環(huán)境下做了一組吞吐量對比的實驗,發(fā)現(xiàn)多線程環(huán)境下,synchronized的吞吐量下降的非常嚴(yán)重,而ReentrankLock則能基本保持在同一個比較穩(wěn)定的水平上。但與其說ReetrantLock性能好,倒不如說synchronized還有非常大的優(yōu)化余地,于是到了JDK1.6,發(fā)生了變化,對synchronize加入了很多優(yōu)化措施,有自適應(yīng)自旋,鎖消除,鎖粗化,輕量級鎖,偏向鎖等等。導(dǎo)致在JDK1.6上synchronize的性能并不比Lock差。官方也表示,他們也更支持synchronize,在未來的版本中還有優(yōu)化余地,所以還是提倡在synchronized能實現(xiàn)需求的情況下,優(yōu)先考慮使用synchronized來進行同步。

   下面淺析以下兩種鎖機制的底層的實現(xiàn)策略。

    互斥同步最主要的問題就是進行線程阻塞和喚醒所帶來的性能問題,因而這種同步又稱為阻塞同步,它屬于一種悲觀的并發(fā)策略,即線程獲得的是獨占鎖。獨占鎖意味著其他線程只能依靠阻塞來等待線程釋放鎖。而在CPU轉(zhuǎn)換線程阻塞時會引起線程上下文切換,當(dāng)有很多線程競爭鎖的時候,會引起CPU頻繁的上下文切換導(dǎo)致效率很低。synchronized采用的便是這種并發(fā)策略。

    隨著指令集的發(fā)展,我們有了另一種選擇:基于沖突檢測的樂觀并發(fā)策略,通俗地講就是先進性操作,如果沒有其他線程爭用共享數(shù)據(jù),那操作就成功了,如果共享數(shù)據(jù)被爭用,產(chǎn)生了沖突,那就再進行其他的補償措施(最常見的補償措施就是不斷地重拾,直到試成功為止),這種樂觀的并發(fā)策略的許多實現(xiàn)都不需要把線程掛起,因此這種同步被稱為非阻塞同步。ReetrantLock采用的便是這種并發(fā)策略。

    在樂觀的并發(fā)策略中,需要操作和沖突檢測這兩個步驟具備原子性,它靠硬件指令來保證,這里用的是CAS操作(Compare and Swap)。JDK1.5之后,Java程序才可以使用CAS操作。我們可以進一步研究ReentrantLock的源代碼,會發(fā)現(xiàn)其中比較重要的獲得鎖的一個方法是compareAndSetState,這里其實就是調(diào)用的CPU提供的特殊指令?,F(xiàn)代的CPU提供了指令,可以自動更新共享數(shù)據(jù),而且能夠檢測到其他線程的干擾,而compareAndSet() 就用這些代替了鎖定。這個算法稱作非阻塞算法,意思是一個線程的失敗或者掛起不應(yīng)該影響其他線程的失敗或掛起。

    Java 5中引入了注入AutomicInteger、AutomicLong、AutomicReference等特殊的原子性變量類,它們提供的如:compareAndSet()、incrementAndSet()和getAndIncrement()等方法都使用了CAS操作。因此,它們都是由硬件指令來保證的原子方法。

   用途比較

    基本語法上,ReentrantLock與synchronized很相似,它們都具備一樣的線程重入特性,只是代碼寫法上有點區(qū)別而已,一個表現(xiàn)為API層面的互斥鎖(Lock),一個表現(xiàn)為原生語法層面的互斥鎖(synchronized)。ReentrantLock相對synchronized而言還是增加了一些高級功能,主要有以下三項:

    1、等待可中斷:當(dāng)持有鎖的線程長期不釋放鎖時,正在等待的線程可以選擇放棄等待,改為處理其他事情,它對處理執(zhí)行時間非常上的同步塊很有幫助。而在等待由synchronized產(chǎn)生的互斥鎖時,會一直阻塞,是不能被中斷的。

    2、可實現(xiàn)公平鎖:多個線程在等待同一個鎖時,必須按照申請鎖的時間順序排隊等待,而非公平鎖則不保證這點,在鎖釋放時,任何一個等待鎖的線程都有機會獲得鎖。synchronized中的鎖時非公平鎖,ReentrantLock默認(rèn)情況下也是非公平鎖,但可以通過構(gòu)造方法ReentrantLock(ture)來要求使用公平鎖。

    3、鎖可以綁定多個條件:ReentrantLock對象可以同時綁定多個Condition對象(名曰:條件變量或條件隊列),而在synchronized中,鎖對象的wait()和notify()或notifyAll()方法可以實現(xiàn)一個隱含條件,但如果要和多于一個的條件關(guān)聯(lián)的時候,就不得不額外地添加一個鎖,而ReentrantLock則無需這么做,只需要多次調(diào)用newCondition()方法即可。而且我們還可以通過綁定Condition對象來判斷當(dāng)前線程通知的是哪些線程(即與Condition對象綁定在一起的其他線程)。

可中斷鎖

    ReetrantLock有兩種鎖:忽略中斷鎖和響應(yīng)中斷鎖。忽略中斷鎖與synchronized實現(xiàn)的互斥鎖一樣,不能響應(yīng)中斷,而響應(yīng)中斷鎖可以響應(yīng)中斷。

    如果某一線程A正在執(zhí)行鎖中的代碼,另一線程B正在等待獲取該鎖,可能由于等待時間過長,線程B不想等待了,想先處理其他事情,我們可以讓它中斷自己或者在別的線程中中斷它,如果此時ReetrantLock提供的是忽略中斷鎖,則它不會去理會該中斷,而是讓線程B繼續(xù)等待,而如果此時ReetrantLock提供的是響應(yīng)中斷鎖,那么它便會處理中斷,讓線程B放棄等待,轉(zhuǎn)而去處理其他事情。

  獲得響應(yīng)中斷鎖的一般形式如下:

	ReentrantLock lock = new ReentrantLock();
	...........
	lock.lockInterruptibly();//獲取響應(yīng)中斷鎖
	try {
	  //更新對象的狀態(tài)
	  //捕獲異常,必要時恢復(fù)到原來的不變約束
	  //如果有return語句,放在這里
	}finally{
		lock.unlock();  //鎖必須在finally塊中釋放
	}

    這里有一個不錯的分析中斷的示例代碼(摘自網(wǎng)上)

    當(dāng)用synchronized中斷對互斥鎖的等待時,并不起作用,該線程依然會一直等待,如下面的實例:

public class Buffer {
 
 private Object lock;
 
 public Buffer() {
  lock = this;
 }
 
 public void write() {
  synchronized (lock) {
   long startTime = System.currentTimeMillis();
   System.out.println("開始往這個buff寫入數(shù)據(jù)…");
   for (;;)// 模擬要處理很長時間 
   {
    if (System.currentTimeMillis()
      - startTime > Integer.MAX_VALUE) {
     break;
    }
   }
   System.out.println("終于寫完了");
  }
 }
 
 public void read() {
  synchronized (lock) {
   System.out.println("從這個buff讀數(shù)據(jù)");
  }
 }
 
 public static void main(String[] args) {
  Buffer buff = new Buffer();
 
  final Writer writer = new Writer(buff);
  final Reader reader = new Reader(buff);
 
  writer.start();
  reader.start();
 
  new Thread(new Runnable() {
 
   @Override
   public void run() {
    long start = System.currentTimeMillis();
    for (;;) {
     //等5秒鐘去中斷讀 
     if (System.currentTimeMillis()
       - start > 5000) {
      System.out.println("不等了,嘗試中斷");
      reader.interrupt(); //嘗試中斷讀線程
      break;
     }
 
    }
 
   }
  }).start();
  // 我們期待“讀”這個線程能退出等待鎖,可是事與愿違,一旦讀這個線程發(fā)現(xiàn)自己得不到鎖,
  // 就一直開始等待了,就算它等死,也得不到鎖,因為寫線程要21億秒才能完成 T_T ,即使我們中斷它,
  // 它都不來響應(yīng)下,看來真的要等死了。這個時候,ReentrantLock給了一種機制讓我們來響應(yīng)中斷,
  // 讓“讀”能伸能屈,勇敢放棄對這個鎖的等待。我們來改寫B(tài)uffer這個類,就叫BufferInterruptibly吧,可中斷緩存。
 }
}
 
class Writer extends Thread {
 
 private Buffer buff;
 
 public Writer(Buffer buff) {
  this.buff = buff;
 }
 
 @Override
 public void run() {
  buff.write();
 }
}
 
class Reader extends Thread {
 
 private Buffer buff;
 
 public Reader(Buffer buff) {
  this.buff = buff;
 }
 
 @Override
 public void run() {
 
  buff.read();//這里估計會一直阻塞 
 
  System.out.println("讀結(jié)束");
 
 }
}

    執(zhí)行結(jié)果如下:

   

 我們等待了很久,后面依然沒有輸出,說明讀線程對互斥鎖的等待并沒有被中斷,也就是該戶吃鎖沒有響應(yīng)對讀線程的中斷。    我們再將上面代碼中synchronized的互斥鎖改為ReentrantLock的響應(yīng)中斷鎖,即改為如下代碼: 

import java.util.concurrent.locks.ReentrantLock;
 
public class BufferInterruptibly {
 
 private ReentrantLock lock = new ReentrantLock();
 
 public void write() {
  lock.lock();
  try {
   long startTime = System.currentTimeMillis();
   System.out.println("開始往這個buff寫入數(shù)據(jù)…");
   for (;;)// 模擬要處理很長時間 
   {
    if (System.currentTimeMillis()
      - startTime > Integer.MAX_VALUE) {
     break;
    }
   }
   System.out.println("終于寫完了");
  } finally {
   lock.unlock();
  }
 }
 
 public void read() throws InterruptedException {
  lock.lockInterruptibly();// 注意這里,可以響應(yīng)中斷 
  try {
   System.out.println("從這個buff讀數(shù)據(jù)");
  } finally {
   lock.unlock();
  }
 }
 
 public static void main(String args[]) {
  BufferInterruptibly buff = new BufferInterruptibly();
 
  final Writer2 writer = new Writer2(buff);
  final Reader2 reader = new Reader2(buff);
 
  writer.start();
  reader.start();
 
  new Thread(new Runnable() {
 
   @Override
   public void run() {
    long start = System.currentTimeMillis();
    for (;;) {
     if (System.currentTimeMillis()
       - start > 5000) {
      System.out.println("不等了,嘗試中斷");
      reader.interrupt(); //此處中斷讀操作
      break;
     }
    }
   }
  }).start();
 
 }
}
 
class Reader2 extends Thread {
 
 private BufferInterruptibly buff;
 
 public Reader2(BufferInterruptibly buff) {
  this.buff = buff;
 }
 
 @Override
 public void run() {
 
  try {
   buff.read();//可以收到中斷的異常,從而有效退出 
  } catch (InterruptedException e) {
   System.out.println("我不讀了");
  }
 
  System.out.println("讀結(jié)束");
 
 }
}
 
class Writer2 extends Thread {
 
 private BufferInterruptibly buff;
 
 public Writer2(BufferInterruptibly buff) {
  this.buff = buff;
 }
 
 @Override
 public void run() {
  buff.write();
 }
 
}

   執(zhí)行結(jié)果如下:

   

 從結(jié)果中可以看出,嘗試中斷后輸出了catch語句塊中的內(nèi)容,也輸出了后面的“讀結(jié)束”,說明線程對互斥鎖的等待被中斷了,也就是該互斥鎖響應(yīng)了對讀線程的中斷。
條件變量實現(xiàn)線程間協(xié)作
    在生產(chǎn)者——消費者模型一文中,我們用synchronized實現(xiàn)互斥,并配合使用Object對象的wait()和notify()或notifyAll()方法來實現(xiàn)線程間協(xié)作。Java 5之后,我們可以用Reentrantlock鎖配合Condition對象上的await()和signal()或signalAll()方法來實現(xiàn)線程間協(xié)作。在ReentrantLock對象上newCondition()可以得到一個Condition對象,可以通過在Condition上調(diào)用await()方法來掛起一個任務(wù)(線程),通過在Condition上調(diào)用signal()來通知任務(wù),從而喚醒一個任務(wù),或者調(diào)用signalAll()來喚醒所有在這個Condition上被其自身掛起的任務(wù)。另外,如果使用了公平鎖,signalAll()的與Condition關(guān)聯(lián)的所有任務(wù)將以FIFO隊列的形式獲取鎖,如果沒有使用公平鎖,則獲取鎖的任務(wù)是隨機的,這樣我們便可以更好地控制處在await狀態(tài)的任務(wù)獲取鎖的順序。與notifyAll()相比,signalAll()是更安全的方式。另外,它可以指定喚醒與自身Condition對象綁定在一起的任務(wù)。
    下面將生產(chǎn)者——消費者模型一文中的代碼改為用條件變量實現(xiàn),如下:

import java.util.concurrent.*;
import java.util.concurrent.locks.*;
 
class Info{	// 定義信息類
	private String name = "name";//定義name屬性,為了與下面set的name屬性區(qū)別開
	private String content = "content" ;// 定義content屬性,為了與下面set的content屬性區(qū)別開
	private boolean flag = true ;	// 設(shè)置標(biāo)志位,初始時先生產(chǎn)
	private Lock lock = new ReentrantLock(); 
	private Condition condition = lock.newCondition(); //產(chǎn)生一個Condition對象
	public void set(String name,String content){
		lock.lock();
		try{
			while(!flag){
				condition.await() ;
			}
			this.setName(name) ;	// 設(shè)置名稱
			Thread.sleep(300) ;
			this.setContent(content) ;	// 設(shè)置內(nèi)容
			flag = false ;	// 改變標(biāo)志位,表示可以取走
			condition.signal();
		}catch(InterruptedException e){
			e.printStackTrace() ;
		}finally{
			lock.unlock();
		}
	}
 
	public void get(){
		lock.lock();
		try{
			while(flag){
				condition.await() ;
			}	
			Thread.sleep(300) ;
			System.out.println(this.getName() + 
				" --> " + this.getContent()) ;
			flag = true ;	// 改變標(biāo)志位,表示可以生產(chǎn)
			condition.signal();
		}catch(InterruptedException e){
			e.printStackTrace() ;
		}finally{
			lock.unlock();
		}
	}
 
	public void setName(String name){
		this.name = name ;
	}
	public void setContent(String content){
		this.content = content ;
	}
	public String getName(){
		return this.name ;
	}
	public String getContent(){
		return this.content ;
	}
}
class Producer implements Runnable{	// 通過Runnable實現(xiàn)多線程
	private Info info = null ;		// 保存Info引用
	public Producer(Info info){
		this.info = info ;
	}
	public void run(){
		boolean flag = true ;	// 定義標(biāo)記位
		for(int i=0;i<10;i++){
			if(flag){
				this.info.set("姓名--1","內(nèi)容--1") ;	// 設(shè)置名稱
				flag = false ;
			}else{
				this.info.set("姓名--2","內(nèi)容--2") ;	// 設(shè)置名稱
				flag = true ;
			}
		}
	}
}
class Consumer implements Runnable{
	private Info info = null ;
	public Consumer(Info info){
		this.info = info ;
	}
	public void run(){
		for(int i=0;i<10;i++){
			this.info.get() ;
		}
	}
}
public class ThreadCaseDemo{
	public static void main(String args[]){
		Info info = new Info();	// 實例化Info對象
		Producer pro = new Producer(info) ;	// 生產(chǎn)者
		Consumer con = new Consumer(info) ;	// 消費者
		new Thread(pro).start() ;
		//啟動了生產(chǎn)者線程后,再啟動消費者線程
		try{
			Thread.sleep(500) ;
		}catch(InterruptedException e){
			e.printStackTrace() ;
		}
 
		new Thread(con).start() ;
	}
}

    執(zhí)行后,同樣可以得到如下的結(jié)果:

姓名--1 --> 內(nèi)容--1
姓名--2 --> 內(nèi)容--2
姓名--1 --> 內(nèi)容--1
姓名--2 --> 內(nèi)容--2
姓名--1 --> 內(nèi)容--1
姓名--2 --> 內(nèi)容--2
姓名--1 --> 內(nèi)容--1
姓名--2 --> 內(nèi)容--2
姓名--1 --> 內(nèi)容--1
姓名--2 --> 內(nèi)容--2

    從以上并不能看出用條件變量的await()、signal()、signalAll()方法比用Object對象的wait()、notify()、notifyAll()方法實現(xiàn)線程間協(xié)作有多少優(yōu)點,但它在處理更復(fù)雜的多線程問題時,會有明顯的優(yōu)勢。所以,Lock和Condition對象只有在更加困難的多線程問題中才是必須的。  

讀寫鎖

    另外,synchronized獲取的互斥鎖不僅互斥讀寫操作、寫寫操作,還互斥讀讀操作,而讀讀操作時不會帶來數(shù)據(jù)競爭的,因此對對讀讀操作也互斥的話,會降低性能。Java 5中提供了讀寫鎖,它將讀鎖和寫鎖分離,使得讀讀操作不互斥,獲取讀鎖和寫鎖的一般形式如下:

ReadWriteLock rwl = new ReentrantReadWriteLock();	 
rwl.writeLock().lock() //獲取寫鎖
rwl.readLock().lock() //獲取讀鎖

   用讀鎖來鎖定讀操作,用寫鎖來鎖定寫操作,這樣寫操作和寫操作之間會互斥,讀操作和寫操作之間會互斥,但讀操作和讀操作就不會互斥。

   《Java并發(fā)編程實踐》一書給出了使用 ReentrantLock的最佳時機:

    當(dāng)你需要以下高級特性時,才應(yīng)該使用:可定時的、可輪詢的與可中斷的鎖獲取操作,公平隊列,或者非塊結(jié)構(gòu)的鎖。否則,請使用synchronized。     

到此這篇關(guān)于淺談Java并發(fā)編程之Lock鎖和條件變量的文章就介紹到這了,更多相關(guān)Java并發(fā)編程之Lock鎖和條件變量內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • spring注解在自定義jar包中無法被掃描的解決方案

    spring注解在自定義jar包中無法被掃描的解決方案

    這篇文章主要介紹了spring注解在自定義jar包中無法被掃描的解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-08-08
  • Spring Cloud 服務(wù)網(wǎng)關(guān)Zuul的實現(xiàn)

    Spring Cloud 服務(wù)網(wǎng)關(guān)Zuul的實現(xiàn)

    這篇文章主要介紹了Spring Cloud 服務(wù)網(wǎng)關(guān)Zuul的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-07-07
  • SpringBoot中配置文件pom.xml的使用詳解

    SpringBoot中配置文件pom.xml的使用詳解

    SpringBoot的pom.xml文件是Maven項目的核心配置文件,用于定義項目的依賴、插件、構(gòu)建配置等信息,下面小編就來和大家詳細介紹一下它的具體使用吧
    2025-03-03
  • 強烈推薦這些提升代碼效率的IDEA使用技巧

    強烈推薦這些提升代碼效率的IDEA使用技巧

    在平常的開發(fā)中,發(fā)現(xiàn)一些同事對Idea 使用的不是很熟練,僅僅用來編輯,編譯,不能很好的發(fā)揮Idea 的神奇.整理了下我平常用的一些技巧,希望你能從中學(xué)習(xí)到一些.需要的朋友可以參考下
    2021-05-05
  • java利用Tabula實現(xiàn)對PDF內(nèi)表格數(shù)據(jù)提取

    java利用Tabula實現(xiàn)對PDF內(nèi)表格數(shù)據(jù)提取

    Tabula是一個開源工具,用于從PDF文檔中提取表格數(shù)據(jù),下面小編就來和大家詳細介紹一下java如何通過Tabula對PDF文件內(nèi)表格進行數(shù)據(jù)提取吧
    2023-09-09
  • java實現(xiàn)上傳文件到oss(阿里云)功能示例

    java實現(xiàn)上傳文件到oss(阿里云)功能示例

    這篇文章主要介紹了java實現(xiàn)上傳文件到oss(阿里云)功能,結(jié)合實例形式詳細分析了java上傳文件到阿里云的具體步驟、配置及相關(guān)實現(xiàn)技巧,需要的朋友可以參考下
    2019-11-11
  • 淺談java中的聲明常量為什么要用static修飾

    淺談java中的聲明常量為什么要用static修飾

    這篇文章主要介紹了淺談java中的聲明常量為什么要用static修飾的問題,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-09-09
  • Java中IO的NIO通道解析

    Java中IO的NIO通道解析

    這篇文章主要介紹了Java中IO的NIO通道解析,NIO 提供了與傳統(tǒng) BIO 模型中的 Socket 和 ServerSocket 相對應(yīng)的 SocketChannel 和 ServerSocketChannel 兩種不同的套接字通道實現(xiàn),需要的朋友可以參考下
    2024-01-01
  • java前后端加密解密crypto-js的實現(xiàn)

    java前后端加密解密crypto-js的實現(xiàn)

    這篇文章主要介紹了java前后端加密解密crypto-js的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-05-05
  • Java多線程(單例模式,阻塞隊列,定時器,線程池)詳解

    Java多線程(單例模式,阻塞隊列,定時器,線程池)詳解

    本文是多線程初級入門,主要介紹了多線程單例模式、阻塞隊列、定時器、線程池、多線程面試考點,感興趣的小伙伴可以跟隨小編一起了解一下
    2022-09-09

最新評論

德安县| 江油市| 米林县| 仁寿县| 阳山县| 寻甸| 南投市| 广饶县| 岱山县| 宜丰县| 瑞安市| 曲沃县| 台北市| 巍山| 安塞县| 观塘区| 汾西县| 深泽县| 浑源县| 玉田县| 天水市| 青海省| 微博| 墨竹工卡县| 合水县| 云林县| 南漳县| 浦江县| 宜兰县| 龙岩市| 车险| 岳阳县| 汝阳县| 佳木斯市| 裕民县| 宜兴市| 全州县| 沙雅县| 闻喜县| 玛沁县| 佳木斯市|