日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

使用SynchronousQueue实现生产者/消费者

發(fā)布時(shí)間:2023/12/3 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 使用SynchronousQueue实现生产者/消费者 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Java提供了許多用于并發(fā)支持的有用類中,有一個(gè)我想談一談: SynchronousQueue 。 特別是,我想通過(guò)使用方便的SynchronousQueue作為交換機(jī)制來(lái)完成Producer / Consumer實(shí)現(xiàn)。

除非我們了解SynchronousQueue實(shí)現(xiàn)的內(nèi)幕,否則可能不清楚為什么要使用這種類型的隊(duì)列進(jìn)行生產(chǎn)者/消費(fèi)者通信。 事實(shí)證明,這并不是我們過(guò)去通??紤]的隊(duì)列。 這個(gè)類比只是一個(gè)最多包含一個(gè)元素的集合。

為什么有用? 好吧,有幾個(gè)原因。 從生產(chǎn)者的角度來(lái)看,只能將一個(gè)元素(或消息)存儲(chǔ)到隊(duì)列中。 為了繼續(xù)進(jìn)行下一個(gè)元素(或消息),生產(chǎn)者應(yīng)等到消費(fèi)者使用隊(duì)列中的當(dāng)前元素。 從使用者的角度來(lái)看,它只是輪詢隊(duì)列以查找下一個(gè)可用的元素(或消息)。 很簡(jiǎn)單,但是最大的好處是:生產(chǎn)者發(fā)送消息的速度不能超過(guò)消費(fèi)者處理消息的速度。

這是我最近遇到的用例之一:比較兩個(gè)數(shù)據(jù)庫(kù)表(可能只是巨大的),并檢測(cè)其中包含不同數(shù)據(jù)或數(shù)據(jù)是否相同(副本)。 SynchronousQueue是解決此問(wèn)題的便捷工具:它允許在自己的線程中處理每個(gè)表,并在從兩個(gè)不同的數(shù)據(jù)庫(kù)讀取數(shù)據(jù)時(shí)補(bǔ)償可能的超時(shí)/延遲。

讓我們從定義比較功能開(kāi)始,該功能接受源數(shù)據(jù)源和目標(biāo)數(shù)據(jù)源以及表名(進(jìn)行比較)。 我正在使用Spring框架中非常有用的JdbcTemplate類,因?yàn)樗浅:玫爻橄罅颂幚磉B接和準(zhǔn)備好的語(yǔ)句的所有無(wú)聊的細(xì)節(jié)。

public boolean compare( final DataSource source, final DataSource destination, final String table ) {final JdbcTemplate from = new JdbcTemplate( source );final JdbcTemplate to = new JdbcTemplate( destination ); }

在進(jìn)行任何實(shí)際數(shù)據(jù)比較之前,最好比較一下源數(shù)據(jù)庫(kù)和目標(biāo)數(shù)據(jù)庫(kù)的表行數(shù):

if( from.queryForLong('SELECT count(1) FROM ' + table ) != to.queryForLong('SELECT count(1) FROM ' + table ) ) {return false; }

現(xiàn)在,至少知道表在兩個(gè)數(shù)據(jù)庫(kù)中包含相同數(shù)量的行,我們可以開(kāi)始進(jìn)行數(shù)據(jù)比較。 該算法非常簡(jiǎn)單:

  • 為源(生產(chǎn)者)和目標(biāo)(消費(fèi)者)數(shù)據(jù)庫(kù)創(chuàng)建一個(gè)單獨(dú)的線程
  • 生產(chǎn)者線程從表中讀取單行并將其放入SynchronousQueue
  • 使用者線程還從表中讀取單行,然后向隊(duì)列詢問(wèn)要比較的可用行(必要時(shí)等待),最后比較兩個(gè)結(jié)果集

使用另一大部分Java并發(fā)實(shí)用程序進(jìn)行線程池,讓我們定義一個(gè)具有固定線程數(shù)量的線程池(2)。

final ExecutorService executor = Executors.newFixedThreadPool( 2 ); final SynchronousQueue< List< ? > > resultSets = new SynchronousQueue< List< ? > >();

按照描述的算法,生產(chǎn)者功能可以表示為單個(gè)可調(diào)用項(xiàng):

Callable< Void > producer = new Callable< Void >() {@Overridepublic Void call() throws Exception {from.query( 'SELECT * FROM ' + table,new RowCallbackHandler() {@Overridepublic void processRow(ResultSet rs) throws SQLException {try { List< ? > row = ...; // convert ResultSet to Listif( !resultSets.offer( row, 2, TimeUnit.MINUTES ) ) {throw new SQLException( 'Having more data but consumer has already completed' );}} catch( InterruptedException ex ) {throw new SQLException( 'Having more data but producer has been interrupted' );}}});return null;} };

由于Java語(yǔ)法,該代碼有點(diǎn)冗長(zhǎng),但實(shí)際上并沒(méi)有做很多事情。 從表生成器讀取的每個(gè)結(jié)果集都將轉(zhuǎn)換為一個(gè)列表(由于是樣板,因此省略了實(shí)現(xiàn)),并將其放入隊(duì)列( offer )。 如果隊(duì)列不為空,則生產(chǎn)者將被阻止等待消費(fèi)者完成工作。 使用者可以分別表示為以下可調(diào)用對(duì)象:

Callable< Void > consumer = new Callable< Void >() {@Overridepublic Void call() throws Exception {to.query( 'SELECT * FROM ' + table,new RowCallbackHandler() {@Overridepublic void processRow(ResultSet rs) throws SQLException {try {List< ? > source = resultSets.poll( 2, TimeUnit.MINUTES );if( source == null ) {throw new SQLException( 'Having more data but producer has already completed' );} List< ? > destination = ...; // convert ResultSet to Listif( !source.equals( destination ) ) {throw new SQLException( 'Row data is not the same' );}} catch ( InterruptedException ex ) {throw new SQLException( 'Having more data but consumer has been interrupted' );}}});return null;} };

使用者對(duì)隊(duì)列執(zhí)行反向操作:與其放入數(shù)據(jù),不如將數(shù)據(jù)從隊(duì)列中拉出( poll )。 如果隊(duì)列為空,則阻止消費(fèi)者,等待生產(chǎn)者發(fā)布下一行。 剩下的部分只是提交那些可調(diào)用對(duì)象以執(zhí)行。 Future的get方法返回的任何異常都表明表不包含相同的數(shù)據(jù)(或者從數(shù)據(jù)庫(kù)獲取數(shù)據(jù)存在問(wèn)題):

List< Future< Void > > futures = executor.invokeAll( Arrays.asList( producer, consumer ) );for( final Future< Void > future: futures ) {future.get( 5, TimeUnit.MINUTES );}

參考: Andriy Redko {devmind}博客中的JCG合作伙伴 Andrey Redko 使用SynchronousQueue實(shí)現(xiàn)了生產(chǎn)者/消費(fèi)者 。

翻譯自: https://www.javacodegeeks.com/2013/01/implementing-producerconsumer-using-synchronousqueue.html

總結(jié)

以上是生活随笔為你收集整理的使用SynchronousQueue实现生产者/消费者的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 不卡av在线 | 中文在线不卡 | 免费黄色网址观看 | 国产精品美女视频 | 99re这里只有精品在线 | 国产91一区在线精品 | 午夜之声l性8电台lx8电台 | 67194成人 | 国产理论视频在线观看 | 99精品在线免费视频 | 国产一在线 | 俄罗斯精品一区二区三区 | av一片| 精品无码久久久久久久久 | 告诉我真相俄剧在线观看 | 一区二区三区www | 精品无码三级在线观看视频 | 特黄特色特刺激免费播放 | 性色视频网站 | wwww在线观看 | 欧美做爰啪啪xxxⅹ性 | 性高潮久久久久久 | 亚洲天堂女人 | 国产内射一区 | 日韩视频一区在线观看 | 欧美在线视频精品 | 亚洲欧美日韩系列 | jizz内谢中国亚洲jizz | 免费不卡毛片 | 特大黑人巨交吊性xx | 欧美成视频 | 国产在线精品福利 | 久热伊人 | 日本色一区 | 国产人免费人成免费视频 | 黄色小视频免费看 | 亚洲热热 | 大乳女喂男人吃奶视频 | 中文写幕一区二区三区免费观成熟 | 精品无码一区二区三区爱欲 | 午夜免费剧场 | 欧美性猛交xxxx黑人猛交 | 自拍视频网站 | 羞羞答答一区 | 91亚洲国产 | 成人免费毛片色戒 | 国产农村妇女精品久久久 | 女子spa高潮呻吟抽搐 | 久久露脸 | 夜夜爽妓女8888视频免费观看 | 免费色网站| 欧美在线你懂的 | av色吧| 五月激情小说网 | 日韩美女一区二区三区 | 国产嫩草在线观看 | 琪琪色在线观看 | 日韩精品视频一区二区 | 日韩免费观看av | 欧美性猛交一区二区三区精品 | 欧美巨大荫蒂茸毛毛人妖 | 精品三级电影 | 日本污网站 | 日本激情视频在线 | 牛牛视频在线观看 | 精品久久影院 | 99久久久| 福利片av | 亚洲欧美日韩综合 | 69pao| 四虎av网址| 99色| 中文字幕69页 | 午夜免费剧场 | 凹凸视频一区二区 | 国产情侣一区二区三区 | 亚洲精品丝袜 | 99精品热| 午夜精品久久 | 成人片黄网站久久久免费 | 亚洲福利在线观看 | 91porny九色 | 国产又黄又粗又猛又爽 | 黄毛片在线观看 | 青青视频在线免费观看 | 亚洲黑丝在线 | 欧美18一20男同69gay | 香蕉在线影院 | 国产青青操 | 最新国产毛片 | 欧美精品久久久久久 | 欧美成人h版在线观看 | 草碰在线 | 五月天婷婷爱 | 国产美女喷水视频 | 国产jizz| 18日本xxxxxxxxx95| 免费精品视频一区二区三区 | 色偷偷免费费视频在线 |