AND信号灯和信号灯集-----同步和互斥解决面向对象(两)

AND信号

互斥的上述处理,它是针对仅在进程之间共享的一个关键资源方面。在一些应用。这是一个过程,需要在为了自己的使命后,获得两个或多个其他共享资源运行。

个进程AB。他们都要求訪问共享数据DE

当然,共享数据都应作为临界资源。为此。可为这两个数据分别设置用于相互排斥的信号量DmutexEmutex,并令它们的初值都是1;

AND同步机制的基本思想是:将进程在整个执行过程中须要的所有资源,一次性所有地分配给进程,待进程使用完后再一起释放。仅仅要尚有一个资源未能分配给进程。其他所有可能为之分配的资源也不分配给它。亦即,对若干个临界资源的分配,採取原子操作方式:要么把它所请求的资源所有分配到进程,要么一个也不分配。

由死锁理论可知,这样就可避免上述死锁情况的发生。为此。在wait操作中。添加了一个“AND”条件,故称为AND同步,或称为同一时候wait操作。

伪代码:例如以下:

Swait(S1S2,…。Sn)

  if Si>=1 and … and Sn>=1 then

   for i:=1 to n do

   Si:=Si-1

   endfor

  else

  place the process in the waiting queue associated with the first Si found with Si<1and set the program count of this process to the beginning of Swait operation 

  endif

Ssignal(S1S2。…,Sn)

for i:=1 to n do

  Si:=Si+1

Remove all the process waiting in the queue associated with Si into the ready queue.

endfor。 

Java代码:

package org.hao.andpv;

 

import java.util.ArrayList;

import java.util.List;

import java.util.concurrent.BlockingQueue;

import java.util.concurrent.LinkedBlockingQueue;

 

public class AndPV {

private int[] semaphores;//信号量数组

private List<BlockingQueue<Thread>> queueList=new ArrayList<BlockingQueue<Thread>>();

    //每一个信号量相应的堵塞队列

public AndPV(int[] semaphores) {//设置信号量初值,初始化

this.semaphores=semaphores;

for(int i=0;i<semaphores.length;i++){

queueList.add(new LinkedBlockingQueue<Thread>());

}

}

public synchronized void p(Thread t) {//p原语

int semaphoreIndex=0;

for(;semaphoreIndex<semaphores.length;semaphoreIndex++){//推断每一个条件是否都满足

if(semaphores[semaphoreIndex]<1){//semaphoreIndex个条件不满足

break;

}

}

if(semaphoreIndex<semaphores.length-1){//条件不满足时

queueList.get(semaphoreIndex).add(t);//加入到堵塞队列

try {

synchronized(t){       

   t.wait();//线程堵塞

}

} catch (Exception e) {

}

}else{

for(semaphoreIndex=0;semaphoreIndex<semaphores.length;semaphoreIndex++){

     semaphores[semaphoreIndex]--;//条件满足时。可用资源都减一

}

}

}

public synchronized void v(){ //v原语

for(int semaphoreIndex=0;semaphoreIndex<semaphores.length;semaphoreIndex++){

semaphores[semaphoreIndex]++;//进程执行完,可用资源都增一

if(semaphores[semaphoreIndex]>=0){//semaphoreIndex类有可用资源

Thread t=queueList.get(semaphoreIndex).poll();

synchronized(t){

   t.notify();

   p(t);//推断其它条件是否满足

}

}

}

}

 

}

信号量集

  在记录型信号量机制中。wait(S)signal(S)操作仅能对信号量施以加1或减1操作。意味着每次仅仅能获得或释放一个单位的临界资源。而当一次须要N个某类临界资源时,便要进行Nwait(S)操作。显然这是低效的。此外。在有些情况下。当资源数量低于某一下限值时,便不予以分配。

因而,在每次分配之前,都必须測试该资源的数量,看其是否大于其下限值。基于上述两点,能够对AND信号量机制加以扩充。形成一般化的“信号量集”机制。Swait操作可描写叙述例如以下,当中S为信号量,d为需求值,而t为下限值。 

package org.hao.andpv;

 

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

import java.util.Map;

import java.util.concurrent.BlockingQueue;

import java.util.concurrent.LinkedBlockingQueue;

 

public class CollectPV {

private int[] semaphores;

private List<BlockingQueue<Thread>> queueList=new ArrayList<BlockingQueue<Thread>>();

    private Map<Thread,Integer[]> map=new HashMap<Thread,Integer[]>();//保存第线程的请求

public CollectPV(int[] semaphores) {

this.semaphores=semaphores;

for(int i=0;i<semaphores.length;i++){

queueList.add(new LinkedBlockingQueue<Thread>());

}

}

public synchronized void p(Thread t,Integer[] semas) {

try {

int semaphoreIndex=0;

for(;semaphoreIndex<semaphores.length;semaphoreIndex++){

if(semaphores[semaphoreIndex]<semas[semaphoreIndex]){

break;

}

}

if(semaphoreIndex<semaphores.length){

BlockingQueue<Thread> blockingQueue=queueList.get(semaphoreIndex);

blockingQueue.add(t);

queueList.add(semaphoreIndex, blockingQueue);

map.put(t, semas);

try {

synchronized(t){       

   t.wait();

}

} catch (Exception e) {

}

}else{

for(int semaphoresIndex=0;semaphoresIndex<semaphores.length;semaphoresIndex++){

     semaphores[semaphoresIndex]-=semas[semaphoresIndex];

}

}

} catch (Exception e) {

}

}

public synchronized void v(Integer[] semas){

try {

for(int semaphoreIndex=0;semaphoreIndex<semaphores.length;semaphoreIndex++){

semaphores[semaphoreIndex]+=semas[semaphoreIndex];

if(semaphores[semaphoreIndex]>=0){

Thread t=queueList.get(semaphoreIndex).poll();

synchronized(t){

   t.notify();

   p(t, map.get(t));

}

}

}

} catch (Exception e) {

}

}

 

}

 

版权声明:本文博客原创文章。博客,未经同意,不得转载。

posted @ 2015-08-19 13:55  lcchuguo  阅读(403)  评论(0编辑  收藏  举报