本帖最后由 Sevenette 于 2014-5-21 17:12 编辑
死锁一种情况是两个锁互相嵌套,运行时不和谐两个进程都掐着锁不放这是毕老师将时的例子0.0 可以愉快的copy去玩玩看...
代码应该能看懂吧0.0?视频大概是在day13-day14 (我是35天的那个视频)
- class Ticket implements Runnable
- {
- private int num = 100;
- Object obj = new Object();
- boolean flag = true;
- public void run()
- {
- if(flag)
- while(true)
- {
- synchronized(obj)
- {
- show();
- }
- }
- else
- while(true)
- this.show();
- }
- public synchronized void show()
- {
- synchronized(obj)
- {
- if(num>0)
- {
- try{Thread.sleep(10);}catch (InterruptedException e){}
- System.out.println(Thread.currentThread().getName()+".....sale...."+num--);
- }
- }
- }
- }
- class DeadLockDemo
- {
- public static void main(String[] args)
- {
- Ticket t = new Ticket();
- Thread t1 = new Thread(t);
- Thread t2 = new Thread(t);
- t1.start();
- try{Thread.sleep(10);}catch(InterruptedException e){}
- t.flag = false;
- t2.start();
- }
- }
复制代码
还有一种情况的是在同步里,生产消费模型,notify()方法唤醒本方线程造成所有线程都处于wait()状态,形成死锁。把notify()改成notifyAll()方法就能解决了~
- /*
- 生产者,消费者。
- 多生产者,多消费者的问题。
- if判断标记,只有一次,会导致不该运行的线程运行了。出现了数据错误的情况。
- while判断标记,解决了线程获取执行权后,是否要运行!
- notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。
- notifyAll解决了本方线程一定会唤醒对方线程的问题。
- */
- class Resource
- {
- private String name;
- private int count = 1;
- private boolean flag = false;
- public synchronized void set(String name)//
- {
- while(flag)
- try{this.wait();}catch(InterruptedException e){}// t1 t0
-
- this.name = name + count;//烤鸭1 烤鸭2 烤鸭3
- count++;//2 3 4
- System.out.println(Thread.currentThread().getName()+"...生产者..."+this.name);//生产烤鸭1 生产烤鸭2 生产烤鸭3
- flag = true;
- notifyAll();
- }
- public synchronized void out()// t3
- {
- while(!flag)
- try{this.wait();}catch(InterruptedException e){} //t2 t3
- System.out.println(Thread.currentThread().getName()+"...消费者........"+this.name);//消费烤鸭1
- flag = false;
- notifyAll();
- }
- }
- class Producer implements Runnable
- {
- private Resource r;
- Producer(Resource r)
- {
- this.r = r;
- }
- public void run()
- {
- while(true)
- {
- r.set("烤鸭");
- }
- }
- }
- class Consumer implements Runnable
- {
- private Resource r;
- Consumer(Resource r)
- {
- this.r = r;
- }
- public void run()
- {
- while(true)
- {
- r.out();
- }
- }
- }
- class ProducerConsumerDemo
- {
- public static void main(String[] args)
- {
- Resource r = new Resource();
- Producer pro = new Producer(r);
- Consumer con = new Consumer(r);
- Thread t0 = new Thread(pro);
- Thread t1 = new Thread(pro);
- Thread t2 = new Thread(con);
- Thread t3 = new Thread(con);
- t0.start();
- t1.start();
- t2.start();
- t3.start();
- }
- }
复制代码
或者运用1.5的新特性:Lock和Condition解决。只有Resource资源类中的方法有改动 生产、消费类的代码和上面是一样的 我就不粘贴了0.0
- /*
- jdk1.5以后将同步和锁封装成了对象。
- 并将操作锁的隐式方式定义到了该对象中,
- 将隐式动作变成了显示动作。
- Lock接口: 出现替代了同步代码块或者同步函数。将同步的隐式锁操作变成现实锁操作。
- 同时更为灵活。可以一个锁上加上多组监视器。
- lock():获取锁。
- unlock():释放锁,通常需要定义finally代码块中。
- Condition接口:出现替代了Object中的wait notify notifyAll方法。
- 将这些监视器方法单独进行了封装,变成Condition监视器对象。
- 可以任意锁进行组合。
- await();
- signal();
- signalAll();
- */
- import java.util.concurrent.locks.*;
- class Resource
- {
- private String name;
- private int count = 1;
- private boolean flag = false;
- // 创建一个锁对象。
- Lock lock = new ReentrantLock();
- //通过已有的锁获取该锁上的监视器对象。
- // Condition con = lock.newCondition();
- //通过已有的锁获取两组监视器,一组监视生产者,一组监视消费者。
- Condition producer_con = lock.newCondition();
- Condition consumer_con = lock.newCondition();
-
- public void set(String name)// t0 t1
- {
- lock.lock();
- try {
- while(flag)
- // try{lock.wait();}catch(InterruptedException e){}// t1 t0
- try{producer_con.await();}catch(InterruptedException e){}// t1 t0
-
- this.name = name + count;//烤鸭1 烤鸭2 烤鸭3
- count++;//2 3 4
- System.out.println(Thread.currentThread().getName()+"...生产者5.0..."+this.name);//生产烤鸭1 生产烤鸭2 生产烤鸭3
- flag = true;
- // notifyAll();
- // con.signalAll();
- consumer_con.signal();
- }finally
- {
- lock.unlock();
- }
- }
- public void out()// t2 t3
- {
- lock.lock();
- try
- {
- while(!flag)
- // try{this.wait();}catch(InterruptedException e){} //t2 t3
- try{cousumer_con.await();}catch(InterruptedException e){} //t2 t3
- System.out.println(Thread.currentThread().getName()+"...消费者.5.0......."+this.name);//消费烤鸭1
- flag = false;
- // notifyAll();
- // con.signalAll();
- producer_con.signal();
- }
- finally
- {
- lock.unlock();
- }
- }
- }
复制代码
|