多线程死锁
测试类:
RunnableLock run=new RunnableLock();
Thread th=new Thread(run);
Thread th1=new Thread(run);
th.start();
th1.start();
钥匙类:
public class Dome {
private Dome(){}
public static final Dome dome=new Dome();//自己new自己
}
public class Domes {
private Domes(){}
public static final Domes domes=new Domes();
}
多线程执行类:
public class RunnableLock implements Runnable {
private int i=0;//无限循环的初始值
@Override
public void run() {
while (true){
if (i%2==0){
//先进A同步,再进B同步
synchronized (Dome.dome){//用一个类调用静态方法,作为钥匙
System.out.println("dome");
synchronized (Domes.domes){
System.out.println("domes");
}
}
}else {
//先进B同步,再进A同步
synchronized (Domes.domes){
System.out.println("domes");
synchronized (Dome.dome){
System.out.println("dome");
}
}
}
i++;
}
}
}
详解:
如下图中:
当线程a拿着A锁进入了“外间”的同时,线程b拿着B锁也进入了“外间”;
这时线程a要想进入里间则需要B锁,而B锁正在线程b的手中;
同理,线程b要想进入里间则需要A锁,而A锁正在线程a的手中;
因此,两个线程进入了死锁状态。
线程通信
测试类:
Resource r=new Resource();
Input in=new Input(r);
Output out=new Output(r);
Thread th=new Thread(in);
Thread th1=new Thread(out);
th.start();
th1.start();
资源类:
/*
* 定义资源类,有两个成员变量
* 两条线程,对name,sex赋值*/
public class Resource {
public String name;
public String age;
public boolean flag=false;
}
输入类:
/*
* 输入的线程嘛对资源对象Resource中的成员变量进行赋值
* 一次赋值 张三 18
* 一次赋值 李四 19*/
public class Input implements Runnable{
Resource r;
int i=0;
Input(Resource r){
this.r=r;
}
@Override
public void run() {
while (true){
synchronized (r){
if (r.flag){
try {
r.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (i%2==0){
r.name="张三";
r.age="18";
}else {
r.name="李四";
r.age="19";
}
r.flag=true;
r.notify();
}
i++;
}
}
}
输出类:
/*
* 输出线程,对资源对象Resource中的成员变量进行输出*/
public class Output implements Runnable{
Resource r;
public Output(Resource r){
this.r=r;
}
@Override
public void run() {
while (true){
synchronized (r){
if (!r.flag){
try {
r.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(r.name+" "+r.age);
r.flag=false;
r.notify();
}
}
}
}
详解:
如下图解释;
先设置初始判断 flag=false ;
当flag=false时输出,输出之后将flag重新赋值为true;
当flag=true时输入,输入之后将flag重新赋值为false;
线程通信用到的两个方法:
对象.wait():让线程进入等待状态;
对象.notify():唤醒线程;