您的位置:首页 > 其它

多线程

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. 把警察小偷只建一个类,属性表示他们不同*
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: