黑马程序员技术交流社区

标题: 不懂线程死锁,谁能帮我写个小程序。 [打印本页]

作者: sheng6699    时间: 2014-4-15 08:08
标题: 不懂线程死锁,谁能帮我写个小程序。
本帖最后由 sheng6699 于 2014-4-16 15:17 编辑

谁能帮我写个 java线程死锁。我不会写。不懂原理。
作者: 曹冬明    时间: 2014-4-15 08:32
  1. /**
  2. * 通过两个属性值创建死锁
  3. * 本程序通过两个线程各自锁定一个属性值,这样两个线程都无法结束,造成死锁
  4. * @author Administrator
  5. *
  6. */
  7. public class ThreadSyn2 implements Runnable{

  8. private static Object obj1=new Object();

  9. private static Object obj2=new Object();

  10. /**
  11.   * @param args
  12.   */
  13. public static void main(String[] args) {
  14.   ThreadSyn2 ts1=new ThreadSyn2();
  15.   ThreadSyn2 ts2=new ThreadSyn2();
  16.   
  17.   Thread t1=new Thread(ts1);//线程1
  18.   Thread t2=new Thread(ts2);//线程2
  19.   t1.setName("theOne");
  20.   t2.setName("theTwo");
  21.   
  22.   t1.start();
  23.   t2.start();

  24. }

  25. public void run() {
  26.   String name=Thread.currentThread().getName();
  27.   if(name.equals("theOne")){
  28.    method1(name);
  29.   }else{
  30.    method2(name);
  31.   }
  32.   
  33. }

  34. //线程1的方法锁定obj1,线程2就无法完成
  35. private void method1(String name) {
  36.   System.out.println(name);
  37.   synchronized(obj1){
  38.    try {
  39.     Thread.sleep(1000);
  40.    } catch (InterruptedException e) {
  41.     e.printStackTrace();
  42.    }
  43.    synchronized(obj2){
  44.     System.out.println(obj2);
  45.    }   
  46.   }  
  47. }

  48.     //线程1的方法锁定obj2,线程1就无法完成
  49. private void method2(String name) {
  50.   System.out.println(name);
  51.   synchronized(obj2){
  52.    try {
  53.     Thread.sleep(1000);
  54.    } catch (InterruptedException e) {
  55.     e.printStackTrace();
  56.    }
  57.    synchronized(obj1){
  58.     System.out.println(obj1);
  59.    }
  60.   }  
  61. }
  62. }
复制代码
http://z13574401906.blog.163.com/blog/static/11206731820102841125368/

作者: ^o(孤8o|狼i¤F    时间: 2014-4-15 09:08
同步过程中,如果一个对象占有了一个资源,等待着另一个被其它对象占有的资源,如果这个“其它对象”也正在等待这个对象已经拥有的资源,那么会引起死锁。但也不需要矫枉过正,下边示例并不是一个有潜在引起死锁的例子:

import java.util.ArrayList;
import java.util.List;

public class NameList {
   private List names = new ArrayList();
   public synchronized void add(String name){
      names.add(name);
   }
   
   public synchronized void printAll(){
      for(int i=0;i<names.size();i++){
         System.out.println(names.get(i) + " ");
      }
   }
   
   public static void main(String[] args) {
      final NameList s1 = new NameList();
      for(int i=0;i<2;i++){
         new Thread(){
            public void run(){
               s1.add("A");
               s1.add("B");
               s1.add("C");
               s1.printAll();
               System.out.println();
            }
         }.start();
      }
   }
}

         add(String name)和printAll()都是共享资源s1上的同步方法,绝对不会死锁!java的锁可以认为是可重入的,synchronized 保证一个方法在同一时刻只被一个方法占有,而且必须执行完毕其它线程进入。

      导致死锁的根源在于不适当地运用“synchronized”关键词来管理线程对特定对象的访问。synchronized 关键词的作用是,确保在某个时刻只有一个线程被允许执行特定的代码块,因此,被允许执行的线程首先必须拥有对变量或对象的排他性访问权。当线程访问对象时,线程会给对象加锁,而这个锁导致其它也想访问同一对象的线程被阻塞,直至第一个线程释放它加在对象上的锁。 上述程序,始终锁定了一个对象,那么限制了另外一个线程锁定它,继而执行run的代码体
作者: sheng6699    时间: 2014-4-15 09:26
谢谢 。好像有点懂了。
作者: sheng6699    时间: 2014-4-15 09:27
曹冬明 发表于 2014-4-15 08:32
http://z13574401906.blog.163.com/blog/static/11206731820102841125368/

谢谢了。听不错的
作者: sheng6699    时间: 2014-4-15 09:29
^o(孤8o|狼i¤F 发表于 2014-4-15 09:08
同步过程中,如果一个对象占有了一个资源,等待着另一个被其它对象占有的资源,如果这个“其它对象”也正在 ...

挺详细的。谢谢




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2