版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/wydyd110/article/details/86610214
会猝死也要坚持学完
1 死锁(deadlock)问题
死锁:一组进程中,每个进程都无限等待被该组进程中 另一进程所占有的资源,因而永远无法得到的资源,这种现象称为 进程死锁,这一组进程就称为 死锁进程
银行家算法
仿照银行发放贷款时采取的控制方式而设计的 一种死锁避免算法
哲学家就餐问题
有五个哲学家围坐在一圆桌旁, 桌中央有一盘通心粉,每人面 前有一只空盘子,每两人之间 放一只筷子。每个哲学家的行为是思考,感 到饥饿,然后吃通心粉 为了吃通心粉,每个哲学家必 须拿到两只筷子,并且每个人 只能直接从自己的左边或右边去取筷子(筷子的互斥使用、 不能出现死锁现象)
可靠措施:1 最多允许4个哲学家同时坐在桌子周围
2 仅当一个哲学家左右两边的筷子都可用时,才 允许他拿筷子
3 给所有哲学家编号,奇数号的哲学家必须首先 拿左边的筷子,偶数号的哲学家则反之
1.1 例子
创建3个线程模拟3个游戏者的行为
public class Main {
public static void main(String[] args) {
Balls ball = new Balls();
Player0 p0 = new Player0(ball);
Player1 p1 = new Player1(ball);
Player2 p2 = new Player2(ball);
p0.start();
p1.start();
p2.start();
}
}
class Balls{
//true表示已被拿走,false表示未被拿走
boolean flag0 = false;
boolean flag1 = false;
boolean flag2 = false;
}
class Player0 extends Thread{
private Balls ball;
public Player0(Balls b) {this.ball = b;}
public void run() {
while(true) {
while(ball.flag1==true) {}//若1号球已被拿走,则等待
ball.flag1=true;
while(ball.flag0==true) {}//若0号球已被拿走,则等待
if(ball.flag1==true&&ball.flag0==false) {
ball.flag0=true;
System.out.println("Player0 has got two balls!");
ball.flag1=false;//放下1号球
ball.flag0=false;//放下0号球
try {
sleep(1); //放下后休息1ms
} catch (InterruptedException e) {}
}
}
}
}
class Player1 extends Thread{
private Balls ball;
public Player1(Balls b) {this.ball = b;}
public void run() {
while(true) {
while(ball.flag0==true) {}//若0号球已被拿走,则等待
ball.flag1=true;
while(ball.flag2==true) {}//若2号球已被拿走,则等待
if(ball.flag0==true&&ball.flag2==false) {
ball.flag2=true;
System.out.println("Player1 has got two balls!");
ball.flag0=false;//放下0号球
ball.flag2=false;//放下2号球
try {
sleep(1); //放下后休息1ms
} catch (InterruptedException e) {}
}
}
}
}
class Player2 extends Thread{
private Balls ball;
public Player2(Balls b) {this.ball = b;}
public void run() {
while(true) {
while(ball.flag2==true) {}//若1号球已被拿走,则等待
ball.flag2=true;
while(ball.flag1==true) {}//若0号球已被拿走,则等待
if(ball.flag2==true&&ball.flag1==false) {
ball.flag1=true;
System.out.println("Player0 has got two balls!");
ball.flag2=false;//放下1号球
ball.flag1=false;//放下0号球
try {
sleep(1); //放下后休息1ms
} catch (InterruptedException e) {}
}
}
}
}
运行结果
陷入死锁,没有输出信息
原因分析
因为若刚好3个人都拿到左边的球,都在等右边的球,因为谁都不愿放手,则陷入死锁
解决方案
2 线程的调度
2.1 线程优先级
1 每个Java线程都有一个优先级,1-10之间,默认设为5
2 线程A运行过程中创建线程B,A与B具有相同的优先级
3 可通过setPriority(int prioritt)设置优先级
4 具有相同优先级的线程,Java的处理是随机的
public class Main {
public static void main(String[] args) {
//构造一个线程数组
TestThread[] runners = new TestThread[2];
for(int i = 0; i < 2; i++)
runners[i] = new TestThread(i);
runners[0].setPriority(2);
runners[1].setPriority(3);//优先级相对高
for(int i = 0; i < 2; i++)
runners[i].start();
}
}
class TestThread extends Thread{
private int tick = 1;
private int num;
public TestThread(int num) {
super();
this.num = num;
}
public void run() {
while(tick < 200000) {
tick++;
if((tick % 50000)==0) {//每隔50000进行显示
System.out.println("Thread #" + num +",tick="+tick);
yield();//放弃执行权
}
}
}
}