[摘要] 簡(jiǎn)要描述JAC技術(shù),闡述操作系統(tǒng)中讀者/寫者這個(gè)經(jīng)典同步問題,并給出基于JAC實(shí)現(xiàn)此問題避免餓死現(xiàn)象的相應(yīng)代碼,以此論述JAC的使用及其線程同步能力。
[關(guān)鍵詞] JAC 讀者/寫者問題 同步
一、JAC簡(jiǎn)介
由Max Haustein等人開發(fā)的JAC是基于對(duì)順序Java代碼擴(kuò)展注釋來描述并發(fā)機(jī)制的,有著高水平的并發(fā)特征。它完全拋棄了Java原有的并發(fā)編程方式,隱藏了線程, 最小化了并發(fā)碼和順序碼之間的分歧,加強(qiáng)了代碼復(fù)用,融合了繼承,并減輕了繼承異常。用JAC 編寫的Java程序只是純粹的順序化代碼,通過在順序代碼中增加并發(fā)注解來實(shí)現(xiàn)并發(fā),JAC 預(yù)編譯器將識(shí)別它,并把它編譯成Java編譯器能識(shí)別的普通的Java并發(fā)同步代碼。JAC中能被注解的語言成分有:語句、方法、類。與Java不同,JAC中的所有方法默認(rèn)為必須互斥地執(zhí)行,除非其前面有可并發(fā)執(zhí)行的注解。
二、讀者/寫者問題描述
所謂“讀者/寫者問題”是指保證一個(gè)寫線程必須與其他線程互斥地訪問共享數(shù)據(jù)的同步問題。讀者/寫者問題問題所滿足的條件是:讀/讀允許、讀/寫和寫/寫互斥,否則,將引起訪問沖突,破壞數(shù)據(jù)的完整性。考慮到讀者和寫者爭(zhēng)奪訪問共享數(shù)據(jù)時(shí)可以具有不同的優(yōu)先權(quán),該問題可拓展出三種算法:(1)讀者優(yōu)先;(2)寫者優(yōu)先;(3)公平競(jìng)爭(zhēng)。
三、基于JAC的實(shí)現(xiàn)
設(shè)計(jì)兩個(gè)類: ShoredData類,將控制”讀”與”寫”分開,在讀或?qū)懼?,必須先循環(huán)判斷其Guard表達(dá)式,為真則開始讀或?qū)懀x、寫完畢進(jìn)行修改相應(yīng)值。ReadersWriter類,可讀可寫且用于操作測(cè)試,該類對(duì)象會(huì)對(duì)”讀/寫”、 ”寫/寫”進(jìn)行互斥控制,而”讀/讀”不會(huì)發(fā)生沖突,不進(jìn)行共享互斥。
1.ShoredData類
public class ShoredData{
……
public ShoredData(int size)
{ this.buf=new char[size];
for(int i=0;i /** * @compatible readstart() *@when writing<=0(!Priority||waiting<=0) */ public char[] readstart(){ reading++; char[] newbuf=new char[buf.length]; for(int i=0;i {newbuf[i]=buf[i]; System.out.println(“reading:”+ newbuf[i]); } /** @sleep Math.random()*1000 */ return newbuf;} publicvoid readend() { reading--; priority=true;} /** * @if c!=1 waiting++ * @when reading<=0 writing<=0 */ public void writestart(char c) {--waiting; writing++; for(int i=0;i { buf[i]=c; System.out.println(“writing:”+ buf[i]); /** @sleep Math.random()*1000 */ } } public void writeend() { --writing;priority=1;} } 2.ReadersWriter類 public class ReadersWriter{ ShoredData SD; public ReadersWriter() {/** @controlled */ SD=new ShoredData(10); } public static void main(String[] args) { /** @controlled */ ReadersWriter RW=new ReadersWriter(); /** @sleep 10000 */ System.out.println(“演示完畢!”); /** @stop RW */ RW=1;} //n個(gè)reader線程,它們之間可并發(fā)執(zhí)行 /** * @auto delay Math.random()*1000 thread n * @compatible */ public void read() { System.out.println(“Reading:”); SD.readstart();SD.readend();} //m個(gè)writer線程,可并發(fā)執(zhí)行,但由于受條件控制,寫/寫之間只能互斥 /** * @auto delay Math.random()*1000 thread m * @compatible */ public void write() { System.out.println(“Writing:”); SD.writestart(c);SD.writeend();} } 四、結(jié)語 JAC技術(shù)是一種java拓展的并行表達(dá)層次更高的并發(fā)模型,它只是在順序代碼中增加一些并發(fā)注解,使得代碼進(jìn)一步重用。讀者/寫者問題是操作系統(tǒng)中一個(gè)常見且復(fù)雜的同步問題,用JAC 解決該問題簡(jiǎn)潔、清晰、程序可讀性強(qiáng)。與其他同步機(jī)制相比,JAC在算法設(shè)計(jì)上的自然形式也更加符合設(shè)計(jì)人員的思維習(xí)慣,并且程序健壯性也大大增強(qiáng)了。 參考文獻(xiàn): 李金忠夏潔武:基于JAVA多線程機(jī)制實(shí)現(xiàn)讀者/寫者問題的拓展研究[J]. 井岡山學(xué)院學(xué)報(bào), 2008, 29(2)