码迷,mamicode.com
首页 > 其他好文 > 详细

General Critical Section Problem

时间:2015-05-14 18:19:40      阅读:210      评论:0      收藏:0      [点我收藏+]

标签:

 

  Once I talked about Process Synchronization, and provided a demo program of Search/Insert/Delete Problem.

  As a matter of fact, such Critical Section Problems have a general form: given num different types of threads, as well as all pairs of i and j such that thread type i and type j cannot get access to the critical section together (possibly i==j), describe the behavior of each type of thead so that all of them can work orderly without deadlock or starvation. Search/insert/delete problem is just a single case when num=3, there are other examples such as Reader-Writer Problem and Baboon Crossing Problem.

  The input of such problem should comprise: (1) one integer num indicating the number of thread types; (2) num integers indicating the number of each type of threads; (3) one integer N indicating the number of following input pairs; (4) N integer pairs representing the thread types that cannot coexist in the critical section. For example, for the search/insert/delete problem, we assume there are 100 threads to search, 50 threads to insert and 20 threads to delete, then the input should be:

3
100
50
20
4
0 2
1 1
1 2
2 2

 

  To such problems, thus far I have come up with a naive general solution:

  1 import java.util.concurrent.atomic.*;
  2 import java.util.concurrent.*;
  3 import java.util.*;
  4 import java.io.*;
  5 
  6 class Input {
  7     private Scanner in;
  8     private StringTokenizer tok;
  9     
 10     public Input() {
 11         in = new Scanner(new BufferedInputStream(System.in));
 12     }
 13     public String nextString() {
 14         while  (tok==null||!tok.hasMoreTokens()) {
 15             tok = new StringTokenizer(in.nextLine());
 16         } 
 17         return tok.nextToken();
 18     }
 19     public int nextInt() {
 20         while  (tok==null||!tok.hasMoreTokens()) {
 21             tok = new StringTokenizer(in.nextLine());
 22         } 
 23         return Integer.parseInt(tok.nextToken());
 24     }
 25     public double nextDouble() {
 26         while  (tok==null||!tok.hasMoreTokens()) {
 27             tok = new StringTokenizer(in.nextLine());
 28         } 
 29         return Double.parseDouble(tok.nextToken());
 30     }
 31     public void close() {
 32         in.close();
 33     }
 34 }
 35 
 36 class CSP {
 37     private class Task extends Thread {
 38         private int type;
 39         
 40         public Task(int type) {
 41             this.type = type;
 42         }
 43         public void run() {
 44             try {
 45                 sempAcquire();
 46                 System.out.println("\t"+this+" is working.");
 47                 sempRelease();
 48             } catch (Exception e) {
 49                 System.err.println("TASK RUN Error: "+e);
 50             }
 51         }
 52         private void sempAcquire() throws InterruptedException {
 53             wait.acquire();
 54             if (mutex[type][type]) {
 55                 semp[type][type].acquire();
 56             }
 57             if (cnt[type].getAndIncrement()==0){
 58                 for (int i=0;i<type;i++) {
 59                     if (mutex[type][i]) {
 60                         semp[type][i].acquire();
 61                     }
 62                 }
 63                 for (int i=type+1;i<num;i++) {
 64                     if (mutex[i][type]) {
 65                         semp[i][type].acquire();
 66                     }
 67                 }
 68             }
 69             wait.release();
 70         }
 71         private void sempRelease() {
 72             if (cnt[type].getAndDecrement()==1){
 73                 for (int i=num-1;i>type;i--) {
 74                     if (mutex[i][type]) {
 75                         semp[i][type].release();
 76                     }
 77                 }
 78                 for (int i=type-1;i>=0;i--) {
 79                     if (mutex[type][i]) {
 80                         semp[type][i].release();
 81                     }
 82                 }
 83             }
 84             if (mutex[type][type]) {
 85                 semp[type][type].release();
 86             }
 87         }
 88         public String toString() {
 89             int idxVal = idx[type].getAndIncrement();
 90             return "Task "+type+" #"+idxVal;
 91         }
 92     }
 93     
 94     private int num;
 95     private Task[][] taskArr;
 96     private AtomicInteger[] cnt;
 97     private AtomicInteger[] idx;
 98     private Semaphore wait;
 99     private Semaphore[][] semp;
100     private boolean mutex[][];
101     
102     public CSP(int num) {
103         this.num = num;
104         taskArr = new Task[num][];
105         cnt = new AtomicInteger[num];
106         idx = new AtomicInteger[num];
107         for (int i=0;i<num;i++) {
108             cnt[i] = new AtomicInteger(0);
109             idx[i] = new AtomicInteger(0);
110         }
111         try {
112             wait = new Semaphore(1);
113             semp = new Semaphore[num][];
114             mutex = new boolean[num][];
115             for (int i=0;i<num;i++) {
116                 semp[i] = new Semaphore[i+1];
117                 mutex[i] = new boolean[i+1];
118             }
119         } catch (Exception e) {
120             System.err.println("CSP INIT Error: "+e);
121         }
122     }
123     public void genThread(int type,int n) {
124         taskArr[type] = new Task[n];
125         for (int i=0;i<n;i++) {
126             taskArr[type][i] = new Task(type);
127         }
128     }
129     public void setMutex(int i,int j) {
130         if (j>i) {
131             i += j;
132             j = i-j;
133             i -= j;
134         }
135         mutex[i][j] = true;
136         try {
137             semp[i][j] = new Semaphore(1);
138         } catch (Exception e) {
139             System.err.println("CSP SETMUTEX Error: "+e);
140         }
141     }
142     public void start() {
143         class Pair {
144             public int type,idx;
145             public Pair(int i,int j) {
146                 type = i;
147                 idx = j;
148             }
149         }
150         List<Pair> q = new LinkedList<Pair>();
151         for (int i=0;i<num;i++) {
152             for (int j=0;j<taskArr[i].length;j++) {
153                 q.add(new Pair(i,j));
154             }
155         }
156         Collections.shuffle(q,new Random());
157         while (!q.isEmpty()) {
158             Pair item = q.remove(0);
159             taskArr[item.type][item.idx].start();
160         }
161     }
162     public void join() {
163         try {
164             for (int i=0;i<num;i++) {
165                 for (int j=0;j<taskArr[i].length;j++) {
166                     taskArr[i][j].join();
167                 }
168             }
169         } catch (Exception e) {
170             System.err.println("CSP JOIN Error: "+e);
171         }
172     }
173 }
174 
175 
176 public class Main {
177     
178     public static void main(String[] args) {
179         Input in = new Input();
180         int n = in.nextInt();
181         CSP csp = new CSP(n);
182         for (int i=0;i<n;i++) {
183             csp.genThread(i,in.nextInt());
184         }
185         int m = in.nextInt();
186         for (int i=0;i<m;i++) {
187             csp.setMutex(in.nextInt(),in.nextInt());
188         }
189         in.close();
190         System.out.println("Critical Section Problem:");
191         csp.start();
192         csp.join();
193     }
194 }

 

=======================================================

 

  (1) Premature optimization is the root of all evil.

  (2) Adding manpower to a late software project makes it later.

 

General Critical Section Problem

标签:

原文地址:http://www.cnblogs.com/DevinZ/p/4503585.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!