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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 创出一片辉煌 中级黑马   /  2012-8-14 21:38  /  1447 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

class MyThread implements Runnable{
private int ticket = 5 ; // 假设一共有5张票
Object obj=new Object();
public void run(){
  for(int i=0;i<100;i++){
   synchronized(this){ // 此处若使用synchronized(obj)一样达到同步,为什么使用obj也可以?不知道这两种有什么区别?
    if(ticket>0){ //把此段代码放入同步方法中,请问此时方法中的this和上面的obj是一样吗?和同步代码块中的this是一样吗?
     try{
      Thread.sleep(300) ;
     }catch(InterruptedException e){
      e.printStackTrace() ;
     }
     System.out.println("卖票:ticket = " + ticket-- );
    }
   }
  }
}
      
};
public class SyncDemo02{
public static void main(String args[]){
  MyThread mt = new MyThread() ; // 定义线程对象
  new Thread(mt).start();
  new Thread(mt).start();
  new Thread(mt).start();
  
}
};

评分

参与人数 1技术分 +1 收起 理由
杨志 + 1

查看全部评分

3 个回复

倒序浏览
本帖最后由 杨彪 于 2012-8-14 21:55 编辑

this 代表本类对象的引用
假如 在run方法里面,既有同步代码块,又有同步方法,通过改变同步代码块的锁来测试。
*
* 通过Object和Demo的测试,可以知道同步方法不可能是任意对象锁。
* 那么,它到底是用的哪个锁呢?
* 由于我们曾经讲过任何一个方法里面都有this对象。
* 通过测试,发现,同步方法的锁是this对象。
*/
public class TicketDemo2 implements Runnable {
        private int tickets = 100;

        Object obj = new Object();
        Demo d = new Demo();

        @Override
        public void run() {
                int x = 0;
                while (true) {
                        if (x % 2 == 0) {
                                synchronized (this) {    //     synchronized (d)  假如传的是Demo对象  运行时就会出现问题  而传入Objdect对象也不会出问题 因为Objdect 是所有类的父类
                                        if (tickets > 0) {
                                                try {
                                                        Thread.sleep(10);
                                                } catch (InterruptedException e) {
                                                        e.printStackTrace();
                                                }
                                                System.out.println(Thread.currentThread().getName()
                                                                + "卖出第" + (tickets--) + "票");
                                        }
                                }
                        } else {
                                show();
                        }
                        x++;
                }
        }

        public synchronized void show() {
                if (tickets > 0) {
                        try {
                                Thread.sleep(10);
                        } catch (InterruptedException e) {
                                e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "卖出第"
                                        + (tickets--) + "票");
                }
        }
}

class Demo{}
回复 使用道具 举报
class MyThread implements Runnable{
private int ticket = 5 ; // 假设一共有5张票
Object obj=new Object();
public void run(){
   for(int i=0;i<100;i++){
    synchronized(MyLock.Mylocka){ // 此处若使用synchronized(obj)一样达到同步,为什么使用obj也可以?不知道这两种有什么区

别?
     if(ticket>0){ //把此段代码放入同步方法中,请问此时方法中的this和上面的obj是一样吗?和同步代码块中的this是一样吗?
      try{
       Thread.sleep(300) ;
     }catch(InterruptedException e){
       e.printStackTrace() ;
      }
      System.out.println("卖票:ticket = " + ticket-- );
     }
    }
   }
}
      
};
public class ThreadDemo{
public static void main(String args[]){
   MyThread mt = new MyThread() ; // 定义线程对象
   new Thread(mt).start();
  new Thread(mt).start();
  new Thread(mt).start();
  
}
};


/*

synchronized使用的锁只要是对象的索引就可以了,但是要注意锁一定要相同(例如死锁当中就必须持持有锁)。
        public void run(){
                if(flag){
                       
                        synchronized(MyLock.Mylocka){
                                        System.out.println("if mylocka");
                                        synchronized(MyLock.Mylockb){
                                                System.out.println("if mylockb");
                                        }
                        }
                }
               
                else{
                        synchronized(MyLock.Mylockb){
                                System.out.println("else mylockb");
                                synchronized(MyLock.Mylocka){
                                        System.out.println("else mylocka");
                                }
                        }
                }
        }

从你自己的例子就可以看出你的锁2个都是可以的,所以只要一个锁就可以了,

*/

class MyLock{
        static Object Mylocka = new Object();
       
}
回复 使用道具 举报
楼上说的我不赞同,

synchronized(MyThread.class)  你可以把这个锁放进去编译,也是可以的运行的。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马