更新時(shí)間:2022-10-17 12:52:31 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽1328次
Java阻塞隊(duì)列這個(gè),就是當(dāng)隊(duì)列中沒有數(shù)據(jù)的時(shí)候,線程讀取的話會(huì)等待。當(dāng)隊(duì)列中的數(shù)據(jù)滿的時(shí)候,線程添加數(shù)據(jù)的時(shí)候,也會(huì)等待。
有個(gè)例子很生動(dòng)形象,往盤子里面放雞蛋,只能放固定數(shù)目的。盤子里面沒有雞蛋,無(wú)法從中拿出來(lái)。當(dāng)盤子里滿了,也放不進(jìn)去。直到被拿出去才能在放。
代碼如下,這里設(shè)置的是一個(gè)盤子最多放10個(gè)雞蛋:
package com.thread.two;
import java.util.ArrayList;
import java.util.List;
public class Plate {
List<Object> eggs=new ArrayList<Object>();public synchronized Object getEgg(){while(eggs.size()==0){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
Object egg=null;
for (int i = 0; i < 10; i++) {
egg=eggs.get(i);
System.out.println("拿到雞蛋.........");
}
//Object egg=eggs.get(0);
eggs.clear();
notify();
//System.out.println("拿到雞蛋.........");
return egg;
}
public synchronized void putEgg(Object egg){
while(eggs.size()>9){
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
eggs.add(egg);
notify();
System.out.println("放入雞蛋.........");
}
static class AddThread extends Thread{
private Plate plate;
private Object egg=new Object();
public AddThread(Plate plate){
this.plate=plate;
}
public void run(){
for (int i = 0; i < 1000; i++) {
plate.putEgg(egg);
}
}
}
static class GetThread extends Thread{
private Plate plate;
public GetThread(Plate plate){
this.plate=plate;
}
public void run(){
for (int i = 0; i < 1000; i++) {
plate.getEgg();
}
}
}
public static void main(String[] args) throws InterruptedException {
Plate plate=new Plate();
Thread add=new Thread(new AddThread(plate));
Thread get=new Thread(new GetThread(plate));
add.start();
get.start();
add.join();
get.join();
System.out.println("測(cè)試結(jié)束");
}
}
這個(gè)例子很形象,用線程實(shí)現(xiàn)了上面所說的。
java現(xiàn)在有concurrent包,里面有很多現(xiàn)成的可以用的類,很多是線程安全的,這樣,像上面寫的put或者get,都不需要自己寫同步方法了,這些類已經(jīng)包裝好了。
這里有一個(gè)ArrayBlockingQueue的例子,和上面實(shí)現(xiàn)的差不多。
首先是兩個(gè)線程,分別是put和get。
ThreadPut:
package com.thread.three;
import java.util.concurrent.ArrayBlockingQueue;
public class ThreadPut implements Runnable{
private ArrayBlockingQueue<String> abq=null;
public ThreadPut(ArrayBlockingQueue<String> abq){
this.abq=abq;
}
public void run() {
// TODO Auto-generated method stub
while(true){
System.out.println("要向隊(duì)列中存數(shù)據(jù)了");
try {
Thread.sleep(1000);
abq.put("hi");
System.out.println("存入后,數(shù)據(jù)一共為:"+abq.size());
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
ThreadGet:
package com.thread.three;
import java.util.concurrent.ArrayBlockingQueue;
public class ThreadGet extends Thread {
ArrayBlockingQueue<String> abq=null;
public ThreadGet(ArrayBlockingQueue<String> abq){
this.abq=abq;
}
@Override
public void run() {
// TODO Auto-generated method stub
while(true){
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("我要從隊(duì)列中取數(shù)據(jù)了");
String msg=null;
if (abq.size()>0) {
msg=abq.remove();
}
System.out.println("隊(duì)列中取得的數(shù)據(jù)為:"+msg+",隊(duì)列中還有一共:"+abq.size());
}
}
}
測(cè)試類:
public class ArrayBlockQueueApp {
public static void main(String[] args) {
ExecutorService es=Executors.newCachedThreadPool();
ArrayBlockingQueue<String> abq=new ArrayBlockingQueue<String>(10);
ThreadGet tGet=new ThreadGet(abq);
Thread tPut=new Thread(new ThreadPut(abq));
es.execute(tGet);
es.execute(tPut);
}
}
這些隊(duì)列放消息的話挺不錯(cuò)的。如果大家想了解更多相關(guān)知識(shí),不妨來(lái)關(guān)注一下本站的Java隊(duì)列,里面還有更豐富的知識(shí)等著大家去學(xué)習(xí),相信對(duì)大家一定會(huì)有所幫助的。
相關(guān)閱讀
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
有基礎(chǔ) 直達(dá)就業(yè)
業(yè)余時(shí)間 高薪轉(zhuǎn)行
工作1~3年,加薪神器
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問老師會(huì)電話與您溝通安排學(xué)習(xí)