多线程
2015-11-08 14:40
155 查看
操作系统实验题
哲学家进餐
代码
DiningPhilosophers.java // 参考操作系统书上哲学家进餐问题管程代码 // wait 会释放锁,yield()不会释放锁,故使用了new Thread().yield(); import java.awt.Color; import java.awt.Graphics; public class DiningPhilosophers { public DiningPhilosophers(int x) { size = x; state = new int[size]; // 0-thinking,1-hungry,2-eating p = new Philosopher[size]; for (int i = 0; i < size; i++) { p[i] = new Philosopher(); } } int size; public int[] state; Philosopher[] p; public void draw(Graphics g) { for (int i = 0; i < size; i++) { p[i].draw(g); } } synchronized void test(int x) { int k = x; if (2 != state[(k + 4) % size] && 1 == state[k] && 2 != state[(k + 1) % size]) { state[k] = 2; } } class Philosopher implements Runnable { int i; // 第几位 int x1, y1, x2, y2; // 筷子的位置 int x, y; // 哲学家的位置 MainFrame mf; // 图形化界面 int sleepTime = 3000; public void draw(Graphics g) { Color color = g.getColor(); switch (state[i]) { case 0 : g.setColor(Color.gray); g.fillOval(x, y, 100, 100); g.setColor(Color.black); g.drawString("thinking", x + 40, y + 40); break; case 1 : g.setColor(Color.red); g.fillOval(x, y, 100, 100); g.setColor(Color.black); g.drawString("hungry", x + 40, y + 40); break; case 2 : g.setColor(Color.green); g.fillOval(x, y, 100, 100); g.setColor(Color.black); g.drawString("eating", x + 40, y + 40); g.setColor(Color.yellow); g.drawLine(x1, y1, x2, y2); break; default : break; } g.setColor(color); } public void set(int i, MainFrame mf, int x1, int y1, int x2, int y2, int x, int y) { state[i] = 0; this.mf = mf; this.i = i; this.x1 = x1; this.x2 = x2; this.y1 = y1; this.y2 = y2; this.x = x; this.y = y; } synchronized void pickup() { // System.out.println("up" +i ); state[i] = 1; mf.repaint(); try { Thread.sleep(sleepTime/4); } catch (Exception e) { e.printStackTrace(); } test(i); while (state[i] != 2) { new Thread().yield(); } //主动放弃cpu,过一会在执行。注意要使用while再次判断 state[i] = 2; // System.out.println("eat" +i ); mf.repaint(); try { Thread.sleep(sleepTime); } catch (Exception e) { e.printStackTrace(); } try { Thread.sleep((int) (Math.random() * 7000)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } synchronized void putdown() { // System.out.println("down" +i ); state[i] = 0; test((i + 4) % 5); test((i + 1) % 5); mf.repaint(); try { Thread.sleep(sleepTime); } catch (Exception e) { e.printStackTrace(); } } void think() { state[i] = 0; // System.out.println("think" +i ); try { Thread.sleep((int) (Math.random() * 8000)); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } public void run() { while (true) { think(); pickup(); putdown(); } } } }
ChopstickArray.java //内部类的使用,内部类只供包含它的那个类调用 import java.awt.Color; import java.awt.Graphics; public class ChopstickArray { Chopstick[] chopsticks; int size; public ChopstickArray(int s) { size = s; int x1, y1, x2, y2; chopsticks = new Chopstick[size];// 从正下方顺时针排序 x1 = 400; y1 = 485; x2 = 400; y2 = 435; chopsticks[0] = new Chopstick(0, x1, y1, x2, y2); x1 = (int) (400 - 185 * Math.sin(72.0 / 180 * 3.1415926)); y1 = (int) (300 + 185 * Math.cos(72.0 / 180 * 3.1415926)); x2 = (int) (400 - 135 * Math.sin(72.0 / 180 * 3.1415926)); y2 = (int) (300 + 135 * Math.cos(72.0 / 180 * 3.1415926)); chopsticks[1] = new Chopstick(1, x1, y1, x2, y2); x1 = (int) (400 - 185 * Math.sin(36.0 / 180 * 3.1415926)); y1 = (int) (300 - 185 * Math.cos(36.0 / 180 * 3.1415926)); x2 = (int) (400 - 135 * Math.sin(36.0 / 180 * 3.1415926)); y2 = (int) (300 - 135 * Math.cos(36.0 / 180 * 3.1415926)); chopsticks[2] = new Chopstick(2, x1, y1, x2, y2); x1 = (int) (400 + 185 * Math.sin(36.0 / 180 * 3.1415926)); y1 = (int) (300 - 185 * Math.cos(36.0 / 180 * 3.1415926)); x2 = (int) (400 + 135 * Math.sin(36.0 / 180 * 3.1415926)); y2 = (int) (300 - 135 * Math.cos(36.0 / 180 * 3.1415926)); chopsticks[3] = new Chopstick(3, x1, y1, x2, y2); x1 = (int) (400 + 185 * Math.sin(72.0 / 180 * 3.1415926)); y1 = (int) (300 + 185 * Math.cos(72.0 / 180 * 3.1415926)); x2 = (int) (400 + 135 * Math.sin(72.0 / 180 * 3.1415926)); y2 = (int) (300 + 135 * Math.cos(72.0 / 180 * 3.1415926)); chopsticks[4] = new Chopstick(4, x1, y1, x2, y2); } public void setchopsticstate(int id, boolean bool) { chopsticks[id].used = bool; } public void draw(Graphics g) { for (int i = 0; i < chopsticks.length; i++) { chopsticks[i].draw(g); } } class Chopstick { int x1, y1, x2, y2; private int id; boolean used = false; public void draw(Graphics g) { if (!used) { Color color = g.getColor(); g.setColor(Color.black); g.drawLine(x1, y1, x2, y2); g.setColor(color); } } public Chopstick(int id, int x1, int y1, int x2, int y2) { this.id = id; this.x1 = x1; this.y1 = y1; this.x2 = x2; this.y2 = y2; } } }
MainFrame.java //主类 import java.awt.*; import java.awt.event.*; public class MainFrame extends Frame{ public static final int CIRCLE_RAD = 160; public static final int WIDTH = 800; public static final int HEIGH = 600; DiningPhilosophers dp; ChopstickArray cArray; public void paint(Graphics g) { Color color = g.getColor(); g.setColor(Color.red); g.drawOval(WIDTH / 2 - CIRCLE_RAD, HEIGH / 2 - CIRCLE_RAD, CIRCLE_RAD * 2, CIRCLE_RAD * 2); g.setColor(color); dp.draw(g); for(int i = 0; i < cArray.size ; i++){ if (2 ==dp.state[i] ) { cArray.setchopsticstate((i+4)%5, true); cArray.setchopsticstate(i, true); } } cArray.draw(g); for(int i = 0; i < cArray.size ; i++){ cArray.setchopsticstate(i, false); } } public void init() { dp = new DiningPhilosophers(5); cArray = new ChopstickArray(5); int x, y; int x1, y1, x2, y2; x1 = 400;//从正上方顺时针排序 y1 = 115; x2 = 400; y2 = 165; x = 400 - 50; y = 70 - 50; dp.p[3].set(3,this,x1, y1, x2, y2, x, y); x1 = (int) (400 + 185 * Math.sin(72.0 / 180 * 3.1415926)); y1 = (int) (300 - 185 * Math.cos(72.0 / 180 * 3.1415926)); x2 = (int) (400 + 135 * Math.sin(72.0 / 180 * 3.1415926)); y2 = (int) (300 - 135 * Math.cos(72.0 / 180 * 3.1415926)); x = (int)(400 + 230 * Math.sin(72.0 / 180 * 3.1415926) - 50); y = (int)(300 - 230 * Math.cos(72.0 / 180 * 3.1415926) - 50); dp.p[4].set(4,this,x1, y1, x2, y2, x, y); x1 = (int)(400 + 185 * Math.sin(36.0 / 180 * 3.1415926)); y1 = (int)(300 + 185 * Math.cos(36.0 / 180 * 3.1415926)); x2 = (int)(400 + 135 * Math.sin(36.0 / 180 * 3.1415926)); y2 = (int)(300 + 135 * Math.cos(36.0 / 180 * 3.1415926)); x = (int)(400 + 230 * Math.sin(36.0 / 180 * 3.1415926) - 50); y = (int)(300 + 230 * Math.cos(36.0 / 180 * 3.1415926) - 50); dp.p[0].set(0,this,x1, y1, x2, y2, x, y); x1 = (int)(400 - 185 * Math.sin(36.0 / 180 * 3.1415926)); y1 = (int)(300 + 185 * Math.cos(36.0 / 180 * 3.1415926)); x2 = (int)(400 - 135 * Math.sin(36.0 / 180 * 3.1415926)); y2 = (int)(300 + 135 * Math.cos(36.0 / 180 * 3.1415926)); x = (int)(400 - 230 * Math.sin(36.0 / 180 * 3.1415926) - 50); y = (int)(300 + 230 * Math.cos(36.0 / 180 * 3.1415926) - 50); dp.p[1].set(1,this,x1, y1, x2, y2, x, y); x1 = (int)(400 - 185 * Math.sin(72.0 / 180 * 3.1415926)); y1 = (int)(300 - 185 * Math.cos(72.0 / 180 * 3.1415926)); x2 = (int)(400 - 135 * Math.sin(72.0 / 180 * 3.1415926)); y2 = (int)(300 - 135 * Math.cos(72.0 / 180 * 3.1415926)); x = (int)(400 - 230 * Math.sin(72.0 / 180 * 3.1415926) - 50); y = (int)(300 - 230 * Math.cos(72.0 / 180 * 3.1415926) - 50); dp.p[2].set(2,this,x1, y1, x2, y2, x, y); } public void launchFrame() { init(); setLocation(100, 100); setSize(WIDTH, HEIGH); setTitle("DiningPhilosophers"); setResizable(false); setBackground(Color.white); addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); addKeyListener(new KeyMonitor()); setVisible(true); } public static void main(String[] args) { new MainFrame().launchFrame(); } private class KeyMonitor extends KeyAdapter { public void keyPressed(KeyEvent e) { int key = e.getKeyCode(); if(key == KeyEvent.VK_ENTER) { run(); } } } public void run() { for (int i = 0; i < dp.size; i++) { new Thread(dp.p[i]).start(); } } }
收获
1.wait 会释放锁,yield()不会释放锁,故使用了new Thread().yield();(只是 实现了接口 ,没采用继承,故不能this.yield).线程的两种实现方式(摘)
public class TestThread1 { public static void main(String args[]) { Runner1 r = new Runner1(); r.start(); //r.run(); //Thread t = new Thread(r); //t.start(); for(int i=0; i<100; i++) { System.out.println("Main Thread:------" + i); } } } //class Runner1 implements Runnable { class Runner1 extends Thread { public void run() { for(int i=0; i<100; i++) { System.out.println("Runner1 :" + i); } } }
2.注意主类的引用(可用到主类的函数和信息)和内部类的使用。
生产者消费者问题(带图形化界面的警察与小偷)
代码
ProducerConsumer.java *//参考生产者与消费者* //public class ProducerConsumer { public static void main(String[] args) { } } class WoTou { public int id; WoTou(int id) { this.id = id; } public String toString() { return "WoTou : " + id; } } class SyncStack { int p = 0; int c = 0; int index = 0; WoTou[] arrWT = new WoTou[3]; public synchronized void push(WoTou wt) { while(index == arrWT.length) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); //唤醒除自己外的所有线程 arrWT[index] = wt; index ++; } public synchronized WoTou pop() { while(index == 0) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } this.notifyAll(); index--; return arrWT[index]; } } class Producer implements Runnable { SyncStack ss = null; Producer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0; i<100; i++) { WoTou wt = new WoTou(i); ss.push(wt); ss.p = i ; //可传出值给图形化界面 //System.out.println("生产了: " + wt); try { Thread.sleep((int)(Math.random() * 200)); } catch (InterruptedException e) { e.printStackTrace(); } } } } class Consumer implements Runnable { SyncStack ss = null; Consumer(SyncStack ss) { this.ss = ss; } public void run() { for(int i=0; i<100; i++) { WoTou wt = ss.pop(); ss.c = i ; //System.out.println("消费了: " + wt); try { Thread.sleep((int)(Math.random() * 1000)); } catch (InterruptedException e) { e.printStackTrace(); } } } }
TankClient.java *//参考马士兵的坦克大战* import java.awt.*; import java.awt.event.*; public class TankClient extends Frame { public static final int GAME_WIDTH = 800; public static final int GAME_HEIGHT = 600; boolean init1 = false; boolean init2 = false; SyncStack ss; Producer p; Consumer c; Police police; Theif theif; private static Toolkit tk = Toolkit.getDefaultToolkit(); // 获取默认工具 private static Image[] images = { // 静态 tk.getImage(TankClient.class.getClassLoader().getResource("picture/0.jpg")), // 反射机制,装载到内存 tk.getImage(TankClient.class.getClassLoader().getResource("picture/1.jpg")) }; private class Theif { int x_p = 10, y_p = GAME_HEIGHT / 2; void draw(Graphics g) { Color c = g.getColor(); g.setColor(Color.RED); g.fillOval(x_p + 7 * ss.c, y_p, 5, 5); g.setColor(c); g.drawImage(images[0], x_p + 7 * ss.c, y_p - 40, null); g.drawString("跑了" + ss.p + "步", x_p + 7 * ss.c, y_p - 40); } } private class Police { int x_p = 10, y_p = GAME_HEIGHT / 2; void draw(Graphics g) { Color c = g.getColor(); g.setColor(Color.black); g.fillOval(x_p + 7 * ss.p, y_p, 5, 5); g.setColor(c); g.drawImage(images[1], x_p + 7 * ss.p, y_p, null); g.drawString("跑了" + ss.p + "步", x_p + 7 * ss.p, y_p + 40); } } public void paint(Graphics g) { Color c = g.getColor(); g.setColor(Color.GREEN); g.drawLine(10, GAME_HEIGHT / 2, 710, GAME_HEIGHT / 2); // 画跑道 g.setColor(c); police.draw(g); theif.draw(g); } public void lauchFrame() { this.setLocation(400, 300); this.setSize(GAME_WIDTH, GAME_HEIGHT); this.setTitle("produce and consume"); this.setBackground(Color.blue); this.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); this.addKeyListener(new KeyMonitor()); this.setResizable(false); setVisible(true); ss = new SyncStack(); p = new Producer(ss); c = new Consumer(ss); police = new Police(); theif = new Theif(); } private class KeyMonitor extends KeyAdapter { @Override public void keyPressed(KeyEvent e) { if (KeyEvent.VK_ENTER == e.getKeyCode()) { new Thread(p).start(); new Thread(c).start(); new Thread(new PaintThread()).start(); } } } public static void main(String[] args) { new TankClient().lauchFrame(); } private class PaintThread implements Runnable { public void run() { while (true) { repaint(); try { Thread.sleep(50); } catch (InterruptedException e) { e.printStackTrace(); } } } } }
*可完善的地方
1.把警察,小偷和生产者消费者完全结合,只保留一个
2. 把警察小偷只建一个类,属性表示他们不同*
相关文章推荐
- WIN7 完全卸载oracle11g步骤
- 对boost::shared_from_this的进一步封装
- CSS居中总结
- 手势识别器的用法
- Silverlight将图片转换为byte的实现代码
- HDU 3534 Tree(dfs统计树的直径的数量)
- CSS学习笔记之<盒子模型>
- Flume学习12_Flume Spooling directory source读取文件格式的要求
- 对于重载new函数所遇到的问题记录
- 个人博客配置百度Ueditor--jsp版本
- 【Nginx】启动过程
- Android高级之Volley框架(一):StringRequest
- 查看mysql字符集
- 源码编译安装 clang
- 数据结构实验之栈一:进制转换
- MapReduce架构
- java System.getProperty()可以获取的值
- 博客
- 《leetCode》:Group Anagrams
- iOS巅峰之深拷贝和浅拷贝区别