一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - 簡要分析Java多進程編程的并發控制

簡要分析Java多進程編程的并發控制

2020-01-15 14:31dyyaries JAVA教程

這篇文章介紹了簡要分析Java多進程編程的并發控制,主要針對內存獲取方面,需要的朋友可以參考下

進程間的通訊無非就是讀寫文件,socket通訊或者使用共享內存。
java沒法管理內存,其實他也是靠創建映像文件來實現的。
 共享內存在java中的實現
在jdk1.4中提供的類MappedByteBuffer為我們實現共享內存提供了較好的方法。該緩沖區實際上是一個磁盤文件的內存映像。二者的變化將保持同步,即內存數據發生變化會立刻反映到磁盤文件中,這樣會有效的保證共享內存的實現。

將共享內存和磁盤文件建立聯系的是文件通道類:FileChannel。該類的加入是JDK為了統一對外部設備(文件、網絡接口等)的訪問方法,并且加強了多線程對同一文件進行存取的安全性。例如讀寫操作統一成read和write。這里只是用它來建立共享內存用,它建立了共享內存和磁盤文件之間的一個通道。

打開一個文件建立一個文件通道可以用RandomAccessFile類中的方法getChannel。該方法將直接返回一個文件通道。該文件通道由于對應的文件設為隨機存取文件,一方面可以進行讀寫兩種操作,另一方面使用它不會破壞映像文件的內容(如果用FileOutputStream直接打開一個映像文件會將該文件的大小置為0,當然數據會全部丟失)。這里,如果用 FileOutputStream和FileInputStream則不能理想的實現共享內存的要求,因為這兩個類同時實現自由的讀寫操作要困難得多。

下面的代碼實現了如上功能,它的作用類似UNIX系統中的mmap函數。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 獲得一個只讀的隨機存取文件對象
RandomAccessFile RAFile = new RandomAccessFile(filename,"r");
// 獲得相應的文件通道
FileChannel fc = RAFile.getChannel();
// 取得文件的實際大小,以便映像到共享內存
int size = (int)fc.size();
// 獲得共享內存緩沖區,該共享內存只讀
MappedByteBuffer mapBuf = fc.map(FileChannel.MAP_RO,0,size);
// 獲得一個可讀寫的隨機存取文件對象
RAFile = new RandomAccessFile(filename,"rw");
// 獲得相應的文件通道
fc = RAFile.getChannel();
// 取得文件的實際大小,以便映像到共享內存
size = (int)fc.size();
// 獲得共享內存緩沖區,該共享內存可讀寫
mapBuf = fc.map(FileChannel.MAP_RW,0,size);
// 獲取頭部消息:存取權限
mode = mapBuf.getInt();

如果多個應用映像同一文件名的共享內存,則意味著這多個應用共享了同一內存數據。這些應用對于文件可以具有同等存取權限,一個應用對數據的刷新會更新到多個應用中。
為了防止多個應用同時對共享內存進行寫操作,可以在該共享內存的頭部信息加入寫操作標志。該共享內存的頭部基本信息至少有:

?
1
2
int Length; // 共享內存的長度。
int mode; // 該共享內存目前的存取模式。

 
共享內存的頭部信息是類的私有信息,在多個應用可以對同一共享內存執行寫操作時,開始執行寫操作和結束寫操作時,需調用如下方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public boolean StartWrite()
{
  if(mode == 0) { // 標志為0,則表示可寫
   mode = 1; // 置標志為1,意味著別的應用不可寫該共享內存
   mapBuf.flip();
   mapBuf.putInt(mode); // 寫如共享內存的頭部信息
   return true;
 }
 else {
  return false; // 指明已經有應用在寫該共享內存,本應用不可寫該共享內存
 }
}
public boolean StopWrite()
{
 mode = 0; // 釋放寫權限
 mapBuf.flip();
 mapBuf.putInt(mode); // 寫入共享內存頭部信息
 return true;
}

這里提供的類文件mmap.java封裝了共享內存的基本接口,讀者可以用該類擴展成自己需要的功能全面的類。
 
如果執行寫操作的應用異常中止,那么映像文件的共享內存將不再能執行寫操作。為了在應用異常中止后,寫操作禁止標志自動消除,必須讓運行的應用獲知退出的應用。在多線程應用中,可以用同步方法獲得這樣的效果,但是在多進程中,同步是不起作用的。方法可以采用的多種技巧,這里只是描述一可能的實現:采用文件鎖的方式。寫共享內存應用在獲得對一個共享內存寫權限的時候,除了判斷頭部信息的寫權限標志外,還要判斷一個臨時的鎖文件是否可以得到,如果可以得到,則即使頭部信息的寫權限標志為1(上述),也可以啟動寫權限,其實這已經表明寫權限獲得的應用已經異常退出,這段代碼如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
// 打開一個臨時的文件,注意同一共享內存,該文件名要相同,可以在共享文件名后加后綴“.lock”。
RandomAccessFile fis = new RandomAccessFile("shm.lock","rw");
// 獲得文件通道
FileChannel lockfc = fis.getChannel();
// 獲得文件的獨占鎖,該方法不產生堵塞,立刻返回
FileLock flock = lockfc.tryLock();
// 如果為空,則表明已經有應用占有該鎖
if(flock == null) {
...// 不能執行寫操作
}else {
...// 可以執行寫操作
}

該鎖會在應用異常退出后自動釋放,這正是該處所需要的方法。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 17个农民工婉莹第一部 | 男人的天堂日本 | mm131亚洲精品久久 | 欧美亚洲欧美 | 成人欧美视频在线看免费 | 国色天香论坛社区在线视频 | 国内精品伊人久久大香线焦 | 欧美日本道免费一区二区三区 | 日韩a无吗一区二区三区 | 亚洲人尿尿 | 亚洲春色综合另类网蜜桃 | 亚洲第一二三四区 | 国产白白视频在线观看2 | 国产亚洲精品福利在线 | 草莓丝瓜芭乐樱桃榴莲色多黄 | 日韩视频免费一区二区三区 | 亚洲国产精品自在在线观看 | 国产亚洲精品91 | 黑帮少爷爱上我第8集在线观看 | 四虎4hu永久免费国产精品 | 日本hdxxxx护士 | 国产精品美女久久久久 | 教师波多野结衣在线播放 | 国产亚洲精品美女久久久 | 欧美大陆日韩一区二区三区 | 国产伊人久久 | 3d动漫免费 | 日本无遮挡吸乳视频看看 | 天天夜夜草草久久伊人天堂 | bt7086新片速递亚洲最新合集 | 亚洲成人看片 | 日本免费在线播放 | 国产欧美综合精品一区二区 | 久久婷婷五月综合色丁香花 | 欧美精品成人a多人在线观看 | 国内精品久久久久久久久久久久 | 91人人在线| 成人国产精品一级毛片视频 | 国产清纯女高中生在线观看 | 卫生间被教官做好爽HH视频 | 国产综合亚洲欧美日韩一区二区 |