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

------- 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类中。


你可能感兴趣的:(java学习日志)