欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解Java的线程的优先级以及死锁

程序员文章站 2024-03-05 23:48:37
java线程优先级 需要避免的与多任务处理有关的特殊错误类型是死锁(deadlock)。死锁发生在当两个线程对一对同步对象有循环依赖关系时。例如,假定一个线程进入了对象x...

java线程优先级
需要避免的与多任务处理有关的特殊错误类型是死锁(deadlock)。死锁发生在当两个线程对一对同步对象有循环依赖关系时。例如,假定一个线程进入了对象x的管程而另一个线程进入了对象y的管程。如果x的线程试图调用y的同步方法,它将像预料的一样被锁定。而y的线程同样希望调用x的一些同步方法,线程永远等待,因为为到达x,必须释放自己的y的锁定以使第一个线程可以完成。死锁是很难调试的错误,因为:
通常,它极少发生,只有到两线程的时间段刚好符合时才能发生。
它可能包含多于两个的线程和同步对象(也就是说,死锁在比刚讲述的例子有更多复杂的事件序列的时候可以发生)。

为充分理解死锁,观察它的行为是很有用的。下面的例子生成了两个类,a和b,分别有foo( )和bar( )方法。这两种方法在调用其他类的方法前有一个短暂的停顿。主类,名为deadlock,创建了a和b的实例,然后启动第二个线程去设置死锁环境。foo( )和bar( )方法使用sleep( )强迫死锁现象发生。

// an example of deadlock.
class a {
  synchronized void foo(b b) {
    string name = thread.currentthread().getname();
    system.out.println(name + " entered a.foo");
    try {
      thread.sleep(1000);
    } catch(exception e) {
      system.out.println("a interrupted");
    }
    system.out.println(name + " trying to call b.last()");
    b.last();
  }
  synchronized void last() {
    system.out.println("inside a.last");
  }
}
class b {
  synchronized void bar(a a) {
    string name = thread.currentthread().getname();
    system.out.println(name + " entered b.bar");
    try {
      thread.sleep(1000);
    } catch(exception e) {
      system.out.println("b interrupted");
    }
    system.out.println(name + " trying to call a.last()");
    a.last();
  }
  synchronized void last() {
    system.out.println("inside a.last");
  }
}
class deadlock implements runnable {
  a a = new a();
  b b = new b();
  deadlock() {
    thread.currentthread().setname("mainthread");
    thread t = new thread(this, "racingthread");
    t.start();
    a.foo(b); // get lock on a in this thread.
    system.out.println("back in main thread");
  }
  public void run() {
    b.bar(a); // get lock on b in other thread.
    system.out.println("back in other thread");
  }
  public static void main(string args[]) {
    new deadlock();
  }
}

运行程序后,输出如下:

mainthread entered a.foo
racingthread entered b.bar
mainthread trying to call b.last()
racingthread trying to call a.last()

因为程序死锁,你需要按ctrl-c来结束程序。在pc机上按ctrl-break(或在solaris下按ctrl-\)你可以看到全线程和管程缓冲堆。你会看到racingthread在等待管程a时占用管程b,同时,mainthread占用a等待b。该程序永远都不会结束。像该例阐明的,你的多线程程序经常被锁定,死锁是你首先应检查的问题。

java线程死锁
需要避免的与多任务处理有关的特殊错误类型是死锁(deadlock)。死锁发生在当两个线程对一对同步对象有循环依赖关系时。例如,假定一个线程进入了对象x的管程而另一个线程进入了对象y的管程。如果x的线程试图调用y的同步方法,它将像预料的一样被锁定。而y的线程同样希望调用x的一些同步方法,线程永远等待,因为为到达x,必须释放自己的y的锁定以使第一个线程可以完成。死锁是很难调试的错误,因为:
通常,它极少发生,只有到两线程的时间段刚好符合时才能发生。
它可能包含多于两个的线程和同步对象(也就是说,死锁在比刚讲述的例子有更多复杂的事件序列的时候可以发生)。

为充分理解死锁,观察它的行为是很有用的。下面的例子生成了两个类,a和b,分别有foo( )和bar( )方法。这两种方法在调用其他类的方法前有一个短暂的停顿。主类,名为deadlock,创建了a和b的实例,然后启动第二个线程去设置死锁环境。foo( )和bar( )方法使用sleep( )强迫死锁现象发生。

// an example of deadlock.
class a {
  synchronized void foo(b b) {
    string name = thread.currentthread().getname();
    system.out.println(name + " entered a.foo");
    try {
      thread.sleep(1000);
    } catch(exception e) {
      system.out.println("a interrupted");
    }
    system.out.println(name + " trying to call b.last()");
    b.last();
  }
  synchronized void last() {
    system.out.println("inside a.last");
  }
}
class b {
  synchronized void bar(a a) {
    string name = thread.currentthread().getname();
    system.out.println(name + " entered b.bar");
    try {
      thread.sleep(1000);
    } catch(exception e) {
      system.out.println("b interrupted");
    }
    system.out.println(name + " trying to call a.last()");
    a.last();
  }
  synchronized void last() {
    system.out.println("inside a.last");
  }
}
class deadlock implements runnable {
  a a = new a();
  b b = new b();
  deadlock() {
    thread.currentthread().setname("mainthread");
    thread t = new thread(this, "racingthread");
    t.start();
    a.foo(b); // get lock on a in this thread.
    system.out.println("back in main thread");
  }
  public void run() {
    b.bar(a); // get lock on b in other thread.
    system.out.println("back in other thread");
  }
  public static void main(string args[]) {
    new deadlock();
  }
}

运行程序后,输出如下:

mainthread entered a.foo
racingthread entered b.bar
mainthread trying to call b.last()
racingthread trying to call a.last()

因为程序死锁,你需要按ctrl-c来结束程序。在pc机上按ctrl-break(或在solaris下按ctrl-\)你可以看到全线程和管程缓冲堆。你会看到racingthread在等待管程a时占用管程b,同时,mainthread占用a等待b。该程序永远都不会结束。像该例阐明的,你的多线程程序经常被锁定,死锁是你首先应检查的问题。