利用信号量和P()V()操作实现哲学家就餐问题

 
  
1 /*
2 * To change this template, choose Tools | Templates
3 * and open the template in the editor.
4 */
5
6   package pack1;
7
8
9   import java.awt. * ;
10 import java.awt.event.ActionEvent;
11 import java.awt.event.ActionListener;
12 import java.util. * ;
13 import javax.swing. * ;
14 /**
15 *
16 * @author Administrator
17 */
18 public class Dinner extends JFrame {
19 public JButton jbt_begin = new JButton( " Start " );
20 public JButton jbt_stop = new JButton( " Pause " );
21 public JButton jbt_continue = new JButton( " Continue " );
22 public JButton jbt_end = new JButton( " Exit " );
23
24
25 public JPanel p_north = new JPanel( new GridLayout( 1 , 10 , 2 , 10 ));
26 public JPanel p_center = new JPanel( new GridLayout( 4 , 7 , 80 , 80 ));
27 public JPanel p_left = new JPanel( new GridLayout( 2 , 1 , 2 , 2 ));
28 public JPanel p_right = new JPanel( new GridLayout( 2 , 1 , 2 , 2 ));
29 public JPanel p_south = new JPanel( new GridLayout( 3 , 1 , 2 , 2 ));
30 public JPanel null0 = new JPanel();
31 public JLabel[] j = new JLabel[ 5 ];
32 public JPanel p_all = new JPanel();
33 public JLabel eat = new JLabel( " yellow message _________eating " );
34 public JLabel think = new JLabel( " white message _________thinking " );
35 public JLabel wait = new JLabel( " blue message _________waiting " );
36 Tool tools0 = new Tool( 0 );
37 Tool tools1 = new Tool( 1 );
38 Tool tools2 = new Tool( 2 );
39 Tool tools3 = new Tool( 3 );
40 Tool tools4 = new Tool( 4 );
41
42 People eater0 = new People( 0 ,tools0,tools1);
43 People eater1 = new People( 1 ,tools2,tools1);
44 People eater2 = new People( 2 ,tools2,tools3);
45 People eater3 = new People( 3 ,tools4,tools3);
46 People eater4 = new People( 4 ,tools4,tools0);
47 public Dinner(){
48 jbt_begin.setFont( new Font( " simhei " , Font.PLAIN, 20 ));
49 jbt_stop.setFont( new Font( " simhei " , Font.PLAIN, 20 ));
50 jbt_continue.setFont( new Font( " simhei " , Font.PLAIN, 20 ));
51 jbt_end.setFont( new Font( " simhei " , Font.PLAIN, 20 ));
52 for ( int i = 0 ;i < 5 ;i ++ ){
53 j[i] = new JLabel();
54 j[i].setFont( new Font( " simhei " , Font.PLAIN, 20 ));
55
56 // j[i].setBorder (BorderFactory.createLineBorder (Color.green, 1));
57 }
58 p_center.setBackground(Color.black);
59 p_center.add(j[ 0 ]);
60 p_center.add(j[ 4 ]);
61 p_center.add(j[ 1 ]);
62 p_center.add(j[ 3 ]);
63 p_center.add(j[ 2 ]);
64
65 p_north.setBackground(Color.black);
66 p_north.add(jbt_begin);
67 p_north.add(jbt_stop);
68 p_north.add(jbt_continue);
69 p_north.add(jbt_end);
70 eat.setFont( new Font( " simhei " , Font.PLAIN, 20 ));
71 eat.setForeground(Color.yellow);
72 think.setFont( new Font( " simhei " , Font.PLAIN, 20 ));
73 think.setForeground(Color.white);
74 wait.setFont( new Font( " simhei " , Font.PLAIN, 20 ));
75 wait.setForeground(Color.blue);
76 p_center.setBorder (BorderFactory.createLineBorder (Color.white, 3 ));
77
78 p_south.setBackground(Color.black);
79 p_south.add(eat);
80 p_south.add(think);
81 p_south.add(wait);
82
83
84 p_all.setLayout( new BorderLayout() );
85 p_all.add(p_north,BorderLayout.NORTH);
86 p_all.add(p_center,BorderLayout.CENTER);
87 p_all.add(p_left,BorderLayout.WEST);
88 p_all.add(p_right,BorderLayout.EAST);
89 p_all.add(p_south,BorderLayout.SOUTH);
90 this .add(p_all);
91
92
93 //
94
95 ActionListener listener1 = new Begin_Listener();
96 ActionListener listener2 = new Stop_Listener();
97 ActionListener listener4 = new Continue_Listener();
98 ActionListener listener3 = new Exit_Listener();
99 jbt_begin.addActionListener(listener1);
100 jbt_stop.addActionListener(listener2);
101 jbt_continue.addActionListener(listener4);
102 jbt_end.addActionListener(listener3);
103 // /
104
105
106
107
108 }
109 class Begin_Listener implements ActionListener{
110
111 public void actionPerformed(ActionEvent e) {
112
113 // /
114
115 eater0.start(); // 开始
116 eater1.start();
117 eater2.start();
118 eater3.start();
119 eater4.start();
120 }
121 }
122 class Stop_Listener implements ActionListener {
123
124 public void actionPerformed(ActionEvent e) {
125
126
127 // eater0.setflag_false();
128 // eater1.setflag_false();
129 // eater2.setflag_false();
130 // eater3.setflag_false();
131 // eater4.setflag_false();
132 eater0.suspend(); // 暂停
133 eater1.suspend();
134 eater2.suspend();
135 eater3.suspend();
136 eater4.suspend();
137
138 }
139
140 }
141 // /
142 class Continue_Listener implements ActionListener{
143
144 public void actionPerformed(ActionEvent e) {
145 eater0.resume(); // 恢复
146 eater1.resume();
147 eater2.resume();
148 eater3.resume();
149 eater4.resume();
150
151 }
152 }
153
154 class Exit_Listener implements ActionListener {
155
156 public void actionPerformed(ActionEvent e) {
157 System.exit( 0 ); // 结束
158 }
159
160 }
161
162
163 // public void begin(){
164
165 // }
166
167 public static void main(String[] args) {
168 try {
169 UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); // 尝试使用系统外观
170 } catch (Exception e) {
171 System.err.println( " 不能使用系统外观 " );
172 }
173 Dinner dinnerframe = new Dinner();
174 dinnerframe.setTitle( " 哲学家就餐问题 " );
175 dinnerframe.setSize( 900 , 700 );
176 dinnerframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
177 dinnerframe.setLocationRelativeTo( null );
178 dinnerframe.setVisible( true );
179 }
180 //
181
182 public class Tool {
183 int Tool_name;
184 boolean available;
185 public Tool( int name){
186 this .Tool_name = name;
187 available = true ;
188 }
189
190 public int getname(){
191 return Tool_name;
192 }
193 public synchronized void takeup( int p) { // 鎷胯捣鍔ㄤ綔
194 while ( ! available) {
195 try {
196
197 wait();
198
199 j[p].setForeground(Color.blue);
200 j[p].setText( " 哲学家 " + (p + 1 ) + " : is waiting for 筷子 " + Tool_name);
201
202
203 } catch (InterruptedException e) {
204 e.printStackTrace();
205 }
206 }
207 available = false ;
208 }
209
210 public synchronized void putdown() {
211 available = true ;
212 notify(); // 唤醒等待队列中的一个线程
213 }
214
215
216 }
217 public class People extends Thread{
218 private int People_name;
219 private Tool left_Tool;
220 private Tool right_Tool;
221 private Random random = new Random();
222 public People(){
223
224 }
225 public People( int name,Tool left,Tool right){
226 this .People_name = name;
227 this .left_Tool = left;
228 this .right_Tool = right;
229 }
230
231 public int getname(){
232 return People_name;
233 }
234
235 public void eating(){
236
237 this .left_Tool.takeup( this .People_name);
238 this .right_Tool.takeup( this .People_name);
239 int s1 = this .left_Tool.getname() + 1 ;
240 int s2 = this .right_Tool.getname() + 1 ;
241 j[People_name].setForeground(Color.red);
242 j[People_name].setText( " 哲学家 " + ( this .People_name + 1 ) + " : is eating...using 筷子( " + s1 + " and " + s2 + " ) " );
243
244
245 }
246
247 public void thinking(){
248 this .left_Tool.putdown();
249 this .right_Tool.putdown();
250 j[People_name].setForeground(Color.white);
251 j[People_name].setText( " 哲学家 " + ( this .People_name + 1 ) + " : is thinking.... " );
252
253 }
254 @Override
255
256
257
258 public void run() // 多线程的实现方法run()
259
260 {
261 try {
262
263 sleep(random.nextInt( 3 ));
264
265 }
266
267 catch (InterruptedException e){}
268
269 while ( true ){
270 thinking();
271 try {
272 sleep( 1000 );
273 } catch (InterruptedException e) {
274 }
275
276 eating();
277 try {
278 sleep( 3000 );
279 } catch (InterruptedException e) {
280 }
281
282 }
283
284 }
285
286 }
287 }
288

 

1.在这里,为了解决存在的死锁问题,我规定了名字为偶数号的哲学家先拿起右手的筷子,然后再拿起左手的筷子,从而不会出现每个哲学家都在等等右边的筷子这种死锁状态。

2.定义Tool类和Peope类,Tool类中的拿起筷子和放下筷子操作为对应的pv操作,通过布尔型变量作为信号量,从而给临界资源的访问设置了限制,当临界资源被一进程访问时,其他待进入的进程进入等待队列。

2010061900222078.jpg

 

转载于:https://www.cnblogs.com/SCAU_que/articles/1752478.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值