一.死锁: 过多的同步容易造成死锁 ------------死锁的发生是建立在同步之上的,没有同步就没有死锁
package com.kennosaur.syn;
/**
* 过多的同步方法可能造成死锁
* @author Administrator
*
*/
public class Synchronized03 {
public static void main(String[] args) {
Object g = new Object();
Object m = new Object();
Test t1 = new Test(g, m);
Test2 t2 = new Test2(g, m);
Thread proxy = new Thread(t1);
Thread proxy2 = new Thread(t2);
proxy.start();
proxy2.start();
}
}
class Test implements Runnable{
Object goods;
Object money;
public Test(Object goods, Object money) {
super();
this.goods = goods;
this.money = money;
}
@Override
public void run() {
while (true) {
test();
}
}
public void test() {
synchronized (goods) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(money) {
}
}
System.out.println("一手给货");
}
}
class Test2 implements Runnable{
Object goods ;
Object money ;
public Test2(Object goods, Object money) {
super();
this.goods = goods;
this.money = money;
}
@Override
public void run() {
while (true) {
test();
}
}
public void test() {
synchronized (money) {
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized(goods) {
}
}
System.out.println("一手给钱");
}
}
二.生产者消费者模式 --------不是设计模式,是多线程造成死锁的解决方案
信号灯法
* 生产者消费者模式---信号灯法
* wait() : 等待,释放锁 sleep 不释放锁
* notify()/notifyAll(): 唤醒
* 与synchronized一起使用
Movie.java
package com.kennosaur.producer;
/**
* 一个场景,共同的资源
* 生产者消费者模式---信号灯法
* wait() : 等待,释放锁 sleep 不释放锁
* notify()/notifyAll(): 唤醒
* 与synchronized一起使用
* @author Administrator
*
*/
public class Movie {
private String pic;
//信号灯
//flag--->true 生产者生产,消费者等待,生产完成后通知消费
//flag--->false 消费者消费,生产者等待,消费完后通知生产
private boolean flag = true;
/**
* 播放
* @param pic
*/
public synchronized void play(String pic) {
if(!flag) { //生产者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//开始生产
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
//生产完毕
this.pic = pic;
//通知消费
this.notify();
//生产者停下
this.flag = false;
}
public synchronized void watch() {
if (flag) { //消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//开始消费
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("消费了:"+pic);
//消费完毕
//通知生产
this.notifyAll();
//消费停止
this.flag = true;
}
}
Player.java
package com.kennosaur.producer;
/**
* 生产者
* @author Administrator
*
*/
public class Player implements Runnable{
private Movie m;
public Player(Movie m) {
super();
this.m = m;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
if (i%2==0) {
m.play("左青龙");
System.out.println("==play左青龙=="+i);
}else {
m.play("右白虎");
System.out.println("==play右白虎=="+i);
}
}
}
}
Watcher.java
package com.kennosaur.producer;
public class Watcher implements Runnable{
private Movie m;
public Watcher(Movie m) {
super();
this.m = m;
}
@Override
public void run() {
for (int i = 0; i < 20; i++) {
m.watch();
}
}
}
App.java
package com.kennosaur.producer;
public class App {
public static void main(String[] args) {
//共同资源
Movie m = new Movie();
//多线程
Player p = new Player(m);
Watcher w = new Watcher(m);
new Thread(p).start();
new Thread(w).start();
}
}
管程