java 线程的死锁
多线程共享一个资源的时候需要同步但是过多的同步会导致死锁。
例如生产者和消费者的问题
public class Info {
private String name="曹飞龙";
private int age= 25;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
/**
* 生产者
* @author 曹飛龍
*/
public class Producer implements Runnable {
private Info info;
public Producer(Info info) {
super();
this.info = info;
}
@Override
public void run() {
boolean flag = false;
for (int i = 0; i < 25; i++) {
if (flag) {
this.info.setName("bob");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.info.setAge(20);
flag = false;
} else {
this.info.setName("Marry");
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
this.info.setAge(26);
flag = true;
}
}
}
}
/**
* 消费者
* @author 曹飞龙
*/
public class Consumer implements Runnable {
private Info info;
public Consumer(Info info) {
super();
this.info = info;
}
@Override
public void run() {
for (int i = 0; i < 25; i++) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("name:" + this.info.getName() + " age:"
+ this.info.getAge());
}
}
}
/**
* 测试类
* @author 曹飞龙
*/
public class Test {
public static void main(String[] args) {
Info info = new Info();
Producer producer = new Producer(info);
Consumer consumer = new Consumer(info);
new Thread(producer).start();
new Thread(consumer).start();
}
}
运行结果
name:bob age:26
name:Marry age:20
name:bob age:26
name:Marry age:20
name:bob age:26
name:Marry age:20
name:bob age:26
name:Marry age:20
name:bob age:26
name:Marry age:20
name:bob age:26
name:Marry age:20
name:bob age:26
name:Marry age:20
name:bob age:26
name:Marry age:20
name:bob age:26
name:Marry age:20
name:bob age:26
name:Marry age:20
name:bob age:26
name:Marry age:20
name:bob age:26
name:Marry age:20
name:Marry age:26
可以从结果中看出来姓名和年龄不能相互对应
那么如何解决呢?
加入同步
加入等待和唤醒
先看看加入同步会如何
public class Info {
private String name = "曹飞龙";
private int age = 25;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
//同步填入数据
public synchronized void setInfo(String name, int age)
throws InterruptedException {
this.name = name;
Thread.sleep(1000);
this.age = age;
}
//同步获取数据
public synchronized void getInfo() throws InterruptedException {
Thread.sleep(1000);
System.out.println("age:" + this.getAge() + " name:" + this.getName());
}
}
/**
* 生产者
*
* @author 曹飛龍
*/
public class Producer implements Runnable {
private Info info;
public Producer(Info info) {
super();
this.info = info;
}
@Override
public void run() {
boolean flag = false;
for (int i = 0; i < 25; i++) {
if (flag) {
try {
info.setInfo("bob", 20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flag = false;
} else {
try {
info.setInfo("Marray", 26);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flag = true;
}
}
}
}
/**
* 消费者
*
* @author 曹飞龙
*/
public class Consumer implements Runnable {
private Info info;
public Consumer(Info info) {
super();
this.info = info;
}
@Override
public void run() {
for (int i = 0; i < 25; i++) {
try {
info.getInfo();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* 测试类
* @author 曹飞龙
*/
public class Test {
public static void main(String[] args) {
Info info = new Info();
Producer producer = new Producer(info);
Consumer consumer = new Consumer(info);
new Thread(producer).start();
new Thread(consumer).start();
}
}
运行效果如下:
age:26 name:Marray
age:20 name:bob
age:20 name:bob
age:20 name:bob
age:20 name:bob
age:20 name:bob
age:26 name:Marray
age:26 name:Marray
age:20 name:bob
age:20 name:bob
age:26 name:Marray
age:26 name:Marray
age:26 name:Marray
age:20 name:bob
age:20 name:bob
age:26 name:Marray
age:26 name:Marray
age:26 name:Marray
age:26 name:Marray
age:26 name:Marray
age:26 name:Marray
age:26 name:Marray
age:26 name:Marray
age:26 name:Marray
age:26 name:Marray
现在年龄和姓名的之可以对应但是 出现了多次的重复打印
解决者个问题就需要使用Object类帮忙了、,我们可以使用其中的等待和唤醒操作。
public class Info {
private String name = "曹飞龙";
private int age = 25;
private boolean flag = false;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
// 同步填入数据
public synchronized void setInfo(String name, int age)
throws InterruptedException {
if (!flag) {
super.wait();
}
this.name = name;
Thread.sleep(1000);
this.age = age;
flag = false;
super.notify();
}
// 同步获取数据
public synchronized void getInfo() throws InterruptedException {
if (flag) {
super.wait();
}
Thread.sleep(1000);
System.out.println("age:" + this.getAge() + " name:" + this.getName());
flag = true;
super.notify();
}
}
/**
* 生产者
*
* @author 曹飛龍
*/
public class Producer implements Runnable {
private Info info;
public Producer(Info info) {
super();
this.info = info;
}
@Override
public void run() {
boolean flag = false;
for (int i = 0; i < 25; i++) {
if (flag) {
try {
info.setInfo("bob", 20);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flag = false;
} else {
try {
info.setInfo("Marray", 26);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
flag = true;
}
}
}
}
/**
* 消费者
*
* @author 曹飞龙
*/
public class Consumer implements Runnable {
private Info info;
public Consumer(Info info) {
super();
this.info = info;
}
@Override
public void run() {
for (int i = 0; i < 25; i++) {
try {
info.getInfo();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
/**
* 测试类
* @author 曹飞龙
*/
public class Test {
public static void main(String[] args) {
Info info = new Info();
Producer producer = new Producer(info);
Consumer consumer = new Consumer(info);
new Thread(producer).start();
new Thread(consumer).start();
}
}
运行效果:
age:25 name:曹飞龙
age:26 name:Marray
age:20 name:bob
age:26 name:Marray
age:20 name:bob
age:26 name:Marray
age:20 name:bob
age:26 name:Marray
age:20 name:bob
age:26 name:Marray
age:20 name:bob
age:26 name:Marray
age:20 name:bob
age:26 name:Marray
age:20 name:bob
age:26 name:Marray
age:20 name:bob
age:26 name:Marray
age:20 name:bob
age:26 name:Marray
age:20 name:bob
age:26 name:Marray
age:20 name:bob
age:26 name:Marray
age:20 name:bob
--最后一部分我我自己也不是非常的理解 希望有人能够帮助理解一下
下边的仅仅工参考 有点晕
当生产者线程调用getInfo()同步方法是如果Info类中的flag为false 调用wait()方法使得 object 线程等待
这个时候消费者线程调用getInfo()同步方法flag 为false 所以去的info 里边的姓名和年龄并且调用notify唤醒object线程把flag 标记标记为true
当生产者线程再次调用getInfo()同步方法flag 为true 为info 的姓名和年龄赋值