您的位置:首页 > 职场人生

黑马程序员_多线程的死锁和等待唤醒机制

2014-07-02 23:36 274 查看
------- android培训java培训、期待与您交流!
----------

1.      死锁问题的发生一般是由于同步的嵌套但锁却不同,如下程序:

class MyLock {
    static Object
locka = new Object();
    static Object
lockb = new Object();
}
class DeadLock
extends MyLock implements Runnable {
    private
boolean
flag;
 
    DeadLock(boolean flag) {
       this.flag = flag;
    }
 
    public
void
run() {
       if (flag) {
           //同步代码块的嵌套,锁不同
           synchronized (locka) {
              System.out.println("if locka");
              synchronized (lockb) {
                  System.out.println("if lockb");
              }
           }
       } else {
           //同步代码块的嵌套,锁不同
           synchronized (lockb) {
               System.out.println("else lockb");
              synchronized (locka) {
                  System.out.println("else locka");
              }
           }
       }
 
    }
}
public
class
Test{
    public
static void
main(String[] args) {
       new Thread(new DeadLock(true)).start();
       new Thread(new DeadLock(false)).start();
    }
}

在两个相互嵌套的同步代码块中,锁不相同,当各自拿着对方的锁不放时就会出现死锁现象。

2.    多线程的等待唤醒机制

class Student {
    private String
name;
    private
int
age;
    static
boolean
flag =
false
;
 
    public
synchronized void
set(String name,
int age) {
       if (flag)

//等待,所有等待的线程都存放在线程池里
           try{this.wait();}catch(Exception e){}
           this.name = name;
           this.age = age;
           flag =true;
//唤醒,首先唤醒第一个被等待的线程
           this.notify();
    }
 
    public
synchronized void
out() {
       if (!flag)

//等待,所有等待的线程都存放在线程池里
           try{this.wait();}catch(Exception e){}
           System.out.println("name:" +
name + "age:" +
age);
           flag =
false
;
//唤醒,首先唤醒第一个被等待的线程
           this.notify();
    }
}
class Input
extends
Student implements Runnable {
    private Student
s;
    Input(Student s){
       this.s=s;
    }
    public
void
run() {
       int x = 0;
       while (true) {
              if (x == 0)
                  s.set("林青霞", 27);
              else
                  s.set("擎天柱", 5000);
              x = (x + 1) % 2;
       }
    }
}
class Output
extends
Student implements Runnable {
    private Student
s;
    Output(Student s){
       this.s=s;
    }
    public
void
run() {
       while (true) {
              s.out();
       }
    }
}
public
class
Test11 {
    public
static void
main(String[] args) {
       Student s=new Student();
       new Thread(new Input(s)).start();
       new Thread(new Output(s)).start();
    }
}

wait();

notify();

notifyAll();

都使用在同步中,因为要对持有监视器(锁)的线程操作

所以要使用在同步中,因为只有同步才具有锁

为什么这些方法要定义在Object类中呢?

因为这些方法在操作同步中的线程时,都必须要标识他们所操作线程持有的锁

只有同一个锁上的被等待线程,才可以被同一个锁上的notify()唤醒

不可以对不同锁中的线程进行唤醒

也就是说,等待和唤醒必须是同一个锁

而锁可以是任意对象,所以可以被任意对象调用的方法定义在Object类中。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐