A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 黑马十八期0513 中级黑马   /  2012-11-28 12:24  /  1872 人查看  /  7 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

想在多线程中产生死锁,视频中毕老师新建了一个类,然后在类中新建了两个对象,再在synchronized()中传入对象。
我没有新建类,而是直接在类中新建了两个对象,为什么就不能实现死锁?
class Test implements Runnable
{
Object locka =new Object();     //我是直接在这里寻了两个对象,而不像视频中那样,建立一个类,然后再在类里创建两个静态对象
Object lockb =new Object();
private boolean flag;
Test(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");
    }
   }
  }
}
}
class Noname
{
public static void main(String[] args)
{
  Thread t1 =new Thread(new Test(true));
  Thread t2 =new Thread(new Test(false));
  t1.start();
  t2.start();
}
}

评分

参与人数 1技术分 +1 收起 理由
奋斗的青春 + 1 鼓励分 。

查看全部评分

7 个回复

倒序浏览
public void run()
        {
                if(flag)
                {
                        while(true)
                        {
                                synchronized(MyLock.locka)
                                {
                                        System.out.println(Thread.currentThread().getName()+"...if locka ");
                                        synchronized(MyLock.lockb)
                                        {
                                                System.out.println(Thread.currentThread().getName()+"..if lockb");                                       
                                        }
                                }
                        }
                }
                else
                {
                        while(true)
                        {
                                synchronized(MyLock.lockb)
                                {
                                        System.out.println(Thread.currentThread().getName()+"..else lockb");
                                        synchronized(MyLock.locka)
                                        {
                                                System.out.println(Thread.currentThread().getName()+".....else locka");
                                        }
                                }
                        }
                }
        }
run方法中的代码应该是这个样子的

评分

参与人数 1技术分 +1 收起 理由
奋斗的青春 + 1 赞一个!

查看全部评分

回复 使用道具 举报
坚持远方 发表于 2012-11-28 13:01
public void run()
        {
                if(flag)

这个代码我知道,我只是想知道我的代码哪儿出现了问题。而且你这段代码还少了一段:新建MyLock类。
class MyLock
{
static  Object locka =new Object();
static  Object lockb =new Object();
}
回复 使用道具 举报
姜伟 发表于 2012-11-28 17:11
这个代码我知道,我只是想知道我的代码哪儿出现了问题。而且你这段代码还少了一段:新建MyLock类。
class  ...

你没有建类分开写,就相当于他们获得的不是相同的对象,所以就不是同一把锁,而老师那个是获得同一个对象中的两个object,
回复 使用道具 举报
因为此锁,每个线程,人手两把锁。
而老毕是把锁弄到一个类里边了,不管你几个线程,就用这两个锁,而你是new一个线程,有两个锁。
回复 使用道具 举报
package cn.itcast.thread.dielock;

public class Test {
        public static void main(String[] args) {
                /*
                 * 创建两个相同类型的对象
                 * 使用这两个相同类型的对象来创建两个线程。
                 * 第一个创建时传递参数是a, b
                 * 第二个创建时传递参数是b, a
                 * 启动两个线程
                 */
                DianHuaTing a = new DianHuaTing("A");
                DianHuaTing b = new DianHuaTing("B");
               
                Thread t1 = new Thread(new User(a, b), "zhangSan");
                Thread t2 = new Thread(new User(b, a), "liSi");
               
                t1.start();
                t2.start();
        }
}

/*
* 两个相同类型的对象做属性
* run()方法中使用其中一个对象来调用方法,而另一个对象做为参数!
*/
class User implements Runnable {
        private DianHuaTing from;
        private DianHuaTing to;
       
        public User(DianHuaTing from, DianHuaTing to) {
                this.from = from;
                this.to = to;
        }
       
        /*
         * 对张三而言,from是a
         * 对李四而言,from是b
         */
        public void run() {
                from.to(to);
        }
}

class DianHuaTing {
        private String name;//当前电话厅的名字
       
        public DianHuaTing(String name) {
                this.name = name;
        }
       
        public String getName() {
                return this.name;
        }
        // 需要两个同步方法
        // 参数要一个,类型为本类型
        // 在第一个方法中使用参数调用本类第二个方法
        public synchronized void to(DianHuaTing to) {// 要去的电话厅的名字
                String threadName = Thread.currentThread().getName();
                System.out.println(threadName + ":准备从" + name + "去" + to.getName() + "。");
                to.show(this);
        }
       
        // 第二个方法中什么都不写,也可以!
        public synchronized void show(DianHuaTing to) {
                String threadName = Thread.currentThread().getName();
                System.out.println(threadName + ":已经从" + name + "到达了" + to.getName() + "。");
        }
}

/*
* zhangSan线程调用了a.to(b); -- 监视器是a
* liSi线程调用了b.to(a); -- 监视器是b
* 没有同步互斥,因为使用了不同的监视器对象!
*
* zhangSan线程又执行了b.show() -- 这是在使用b的同步方法,那么监视器是b,而b在被liSi线程使用!
* liSi线程又执行了a.show() -- 这是在使用a的同步方法,那么监视器是a,而a在被zhangSan线程使用!
*/

评分

参与人数 1技术分 +1 收起 理由
古银平 + 1 神马都是浮云

查看全部评分

回复 使用道具 举报
在视频中有加入 while 循环语句,你写的代码中没有while语句。
回复 使用道具 举报
这个程序已经不是死锁问题了,没有实现死锁。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马