多线程

操作系统实验题

哲学家进餐

代码

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. 把警察小偷只建一个类,属性表示他们不同*

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值