线程锁的问题 不太清楚线程执行过程

lvdan86546853 2013-03-21 06:50:07
代码:
public class TT implements Runnable {
int b=100;

public void m1 () throws InterruptedException {
b=1500;
Thread.sleep(5000);
System.out.println("b3="+b);
}

public void m2() throws InterruptedException {
b=2500;
Thread.sleep(2500);
System.out.println("b2="+b);
}


@Override
public void run() {
// TODO Auto-generated method stub

try {
m1();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}

}




public static void main(String[] args) throws InterruptedException {
// TODO Auto-generated method stub
TT tt = new TT();
Thread t = new Thread(tt);
t.start();
tt.m2();
System.out.println("b1="+tt.b);
}
}
输出结果: b2=1500,b1=1500,b3=1500 问题1:谁能具体解析下具体代码的执行过程,为什么m2()要先m1()执行?

问题2:同时在m1(),m2()前加锁,加关键字 synchronized 输出结果b2=2500,b1=2500,b3=1500 ??

问题3:分别给m1(),m2() 单独加锁,结果b2,b1,b3都是1500 ??
谢谢,希望大牛能给点解析,具体怎么执行。
...全文
231 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
lvdan86546853 2013-03-22
  • 打赏
  • 举报
回复
差不多知道怎么回事了。谢谢楼上的各位了。
lvdan86546853 2013-03-22
  • 打赏
  • 举报
回复
引用 3 楼 chengxu2011 的回复:
额 弱弱的问下分别给m1(),m2() 单独加锁是什么意思
貌似我的理解也是,当线程要调用某个被锁的方法,就会锁定这个方法的对象。。 静态的就锁定方法。。。
LCore 2013-03-22
  • 打赏
  • 举报
回复
引用 4 楼 lvdan1 的回复:
引用 2 楼 nmyangym 的回复:个人浅见: 1 关于m2()先于m1()执行,是因为t线程启动后,要等待虚拟机的调度,而m2()就在主线程里运行,(已经在运行了)所以通常是m2()先于m1()运行。m2先执行,会给b赋值2500,但马上休眠了,这会m1会执行,就给b复制1500了,最后输出的都是这个值。 2 关于问题2,m1(),m2()都加上synchr……
其实方法加锁的方法都是差不多的! 只是说给对象进行加锁的时候,有时候比直接给方法加锁性能更高而已 其实说白了给对象加锁,就是控制临界资源的访问权限
    package com.kiritor;  
    /** 
     * @author Kiritor 
     * 饿汉式单例模式*/  
    public class Singleton {  
       private static Singleton singleton = null;  
       private static Object object = new Object();  
       //私有构造方法  
       private Singleton()  
       {  
             
       }  
       public static Singleton getInstance()  
       {  
          <span style="color:#FF0000;"> if(singleton== null)  
           {  
           synchronized(object)  
           {  
               /*这里在做一次的判断是: 
                * 当两个线程同时运行到singleton=null时 
                * 只能有一个A线程运行,另一个B不能运行 
                * 但是当不做这层判断的时候,A执行完成后(有了一个实例a), 
                * B开始执行,由于没有singeton==null的判断B结束之后有了一个实例b 
                * 这样就不能保证单例了*/  
               if(singleton== null)  
                  {  
                      singleton = new Singleton();  
                  }  
           }  
            
           }</span>  
           return singleton;  
                 
       }  
    }  
          
nmyangym 2013-03-22
  • 打赏
  • 举报
回复
"第三问 是没明白方法加锁和对象加锁的不同。。" 个人理解,不妥望指正: 给方法加锁,(就是加上synchronized修饰),就是用当前对象(this)作为同步的对象。他的意义是,在我这个方法运行时,其他线程在运行到了使用这个同步对象作为synchronized修饰的方法或代码块时,要等待;或者在别的线程正在运行使用这个同步对象作为synchronized修饰的方法或代码块时,我这个方法也要等待。 ”对象加锁“,是指对象是被用于做同步用。 如果只给一个方法加上了“锁”,不存在同步对象争用问题,所以没有意义。对楼主的代码,与不加是一样的。
chengxu2011 2013-03-22
  • 打赏
  • 举报
回复
引用 4 楼 lvdan1 的回复:
引用 2 楼 nmyangym 的回复: 个人浅见: 1 关于m2()先于m1()执行,是因为t线程启动后,要等待虚拟机的调度,而m2()就在主线程里运行,(已经在运行了)所以通常是m2()先于m1()运行。m2先执行,会给b赋值2500,但马上休眠了,这会m1会执行,就给b复制1500了,最后输出的都是这个值。 2 关于问题2,m1(),m2()都加上synchroniezd关键字,根……
我很纳闷 对非静态的方法加锁难道不就是对对象加锁么??????????????????
lvdan86546853 2013-03-22
  • 打赏
  • 举报
回复
引用 2 楼 nmyangym 的回复:
个人浅见: 1 关于m2()先于m1()执行,是因为t线程启动后,要等待虚拟机的调度,而m2()就在主线程里运行,(已经在运行了)所以通常是m2()先于m1()运行。m2先执行,会给b赋值2500,但马上休眠了,这会m1会执行,就给b复制1500了,最后输出的都是这个值。 2 关于问题2,m1(),m2()都加上synchroniezd关键字,根据上面1 的分析,……
楼上两位回复的很好,关于问题一二,我原先也是这样想的,一个是在主线程,一个是另一个刚开启的(猜测可能有延迟),第三问 是没明白方法加锁和对象加锁的不同。。 看了上面2位的解释,好像现在明白怎么回事了。 追问一下,怎么给对象进行锁定 ?
chengxu2011 2013-03-22
  • 打赏
  • 举报
回复
额 弱弱的问下分别给m1(),m2() 单独加锁是什么意思
nmyangym 2013-03-21
  • 打赏
  • 举报
回复
个人浅见: 1 关于m2()先于m1()执行,是因为t线程启动后,要等待虚拟机的调度,而m2()就在主线程里运行,(已经在运行了)所以通常是m2()先于m1()运行。m2先执行,会给b赋值2500,但马上休眠了,这会m1会执行,就给b复制1500了,最后输出的都是这个值。 2 关于问题2,m1(),m2()都加上synchroniezd关键字,根据上面1 的分析,m2()先执行,因为加了同步,所以在m2()执行时,t线程是在等待状态,m1()不会执行。m2()执行完后,会输出b2=2500. 但接下来输出可能是b1=2500,也可能是b1=1500. 这块是随机的! 因为m2()执行完后,同步锁释放,m1()会运行,但同时主线程也会继续执行,具体哪个先执行,就无法确定了。如果m1()先执行,会输出b1=1500; 反之会输出b1=2500. 最后b3=1500. 3 问题3,分别加锁就和没加一样,所以输出和1 一样。
LCore 2013-03-21
  • 打赏
  • 举报
回复
引用 楼主 lvdan1 的回复:
代码:Java code?1 public class TT implements Runnable { int b=100; public void m1 () throws InterruptedException { b=1500; Thread.sleep(5000); System.out.println("b3="+b);……
第一问题: m2()是否先与m1()开始执行是无法确定的!这个问题不深究 但是从你的输出可以看出事m2中的b=2500是先于m1中的b=1500执行的 之后b=1500了,但是由于sleep(5000),程序执行到tt.m2(),而m2只是sleep(2500)因此m2方法先执行首先输出b2=1500, 之后程序顺序执行到System.out.println("b1=" + tt.b);输出b1=1500 最后执行m1()输出b3=1500 tips:它们的输出顺序和你睡眠时间有关,但是b的值是一样的! 无非都是1500或则2500, 第二个问题:由于你是锁的方法而非对象,且m1、m2都加了锁形成了同步方法 线程在执行同步方法时是具有排它性的。当任意一个线程进入到一个对象的任意一个同步方法时,这个对象的所有同步方法都被锁定了,在此期间,其他任何线程都不能访问这个对象的任意一个同步方法,直到这个线程执行完它所调用的同步方法并从中退出。 这里m2方法抢先执行此时m1被锁住b=2500; 首先输出b2=2500;之后执行到System.out.println("b1="+tt.b);同样输出b1=2500 最后执行m1,b3=1500,输出b3=1500 第三个问题: 单独加锁:在一个对象被某个线程锁定之后,其他线程是可以访问这个对象的所有非同步方法的。 也就是说,单独加锁的情况和第一种情况是一样的!

62,621

社区成员

发帖
与我相关
我的任务
社区描述
Java 2 Standard Edition
社区管理员
  • Java SE
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧