[求助]关于多线程的运行结果, 请教大牛们

飞火流云 2010-02-24 04:56:38
源码如下:
public class TestThread implements Runnable{

int b =100 ;

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

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

@Override
public void run() {
// TODO Auto-generated method stub
try{
m1();
}catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}

/**
* @param args
*/
public static void main(String[] args) throws Exception{
// TODO Auto-generated method stub
TestThread tr = new TestThread();
Thread tt = new Thread(tr);
tt.start();

tr.m2();
System.out.println("主线程 : b="+tr.b);
// Thread.sleep(1000);
// System.out.println("主线程 : b="+tr.b);

Thread.sleep(10000);
System.out.println("最后结果 : b="+tr.b);

}

}


运行结果:
-------------
主线程 : b=1000
m1(): b=1000
最后结果 : b=1000

这里不明白的是, synchronized的作用不是不同线程只能在同一个对象上加一把锁么?既然一个对象只能有一把锁的话, 那用两个synchronized方法同步访问还是有问题,还不如直接把对象给锁住呢。。。




...全文
127 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
henry_fuzr 2010-02-26
  • 打赏
  • 举报
回复
但是我有一个疑问, 这样由CPU进行线程间的切换的话, 由于m1()和m2()方法都加了锁,那这两个方法在执行的时候tr这个对象应该是被锁住了啊, 既然是锁住的话,


汗 m2执行完 不是释放锁了
飞火流云 2010-02-25
  • 打赏
  • 举报
回复
引用 3 楼 jafapple 的回复:
不会重复加锁,如果是,那么死锁就会像大宝一样,天天见

你的理解有误,这里不是对tr对象进行加锁,而是获取tr对象锁。
意思可以说,我要用tr,得先拿到tr的锁(或者说是钥匙),才能使用。所以怎么可能会重复加锁呢,锁(钥匙)只有一个,谁拿在手里,谁先用,用完归还,没拿到的线程就等待。

线程2没有获取到tr对象锁,他会等待直到主线程从m2()方法执行返回tr锁,然后再获取tr对象锁。


意思是说, 只要执行tr的使用了sychronized关键字的方法,tr对象上就会有锁,无论哪个线程执行都需要获得该锁的钥匙么?
stu202060510 2010-02-25
  • 打赏
  • 举报
回复
为什么是先执行tr.m2(),再执行的m1()?是不是也有可能先执行m1()?高手指教一下
zqfddqr 2010-02-25
  • 打赏
  • 举报
回复
en zhege doushuochabuduole a
小贝壳666 2010-02-24
  • 打赏
  • 举报
回复
只有一个锁,m1想加锁得等m2把锁释放了才行。
xierangh 2010-02-24
  • 打赏
  • 举报
回复
你可以用Thread.currentThread().yield();来保证tt先执行。

实际上你要表现明显的多线程应该再写一个线程来操作b。一个线程不明显。
jafapple 2010-02-24
  • 打赏
  • 举报
回复
不会重复加锁,如果是,那么死锁就会像大宝一样,天天见

你的理解有误,这里不是对tr对象进行加锁,而是获取tr对象锁。
意思可以说,我要用tr,得先拿到tr的锁(或者说是钥匙),才能使用。所以怎么可能会重复加锁呢,锁(钥匙)只有一个,谁拿在手里,谁先用,用完归还,没拿到的线程就等待。

线程2没有获取到tr对象锁,他会等待直到主线程从m2()方法执行返回tr锁,然后再获取tr对象锁。
小贝壳666 2010-02-24
  • 打赏
  • 举报
回复
先运行的tr.m2();
再执行的m1()
tt.start(); 不会马上执行线程,只是放线程池中等待CUP来调度。
先执行的tr.m2();取得对象锁
当tr.m2();执行完成后,m1()取得锁执行。
所以结果都是b=1000
飞火流云 2010-02-24
  • 打赏
  • 举报
回复
syschronized的锁定该对象,指的是TestThread类的对象吧, 那按照这样理解的话,出现这样的结果:

-------------
主线程 : b=1000
m1(): b=1000
最后结果 : b=1000

那分析下执行的顺序:

1. 先是主线程m2()方法执行完"------------------"并将b值由100改为2000,然后时间片结束。
2. 执行线程2的m1()方法将b值由2000改为1000, 然后回到主线程。
3. 执行主线程的 System.out.println("主线程 : b="+tr.b), 得到 主线程 : b=1000
4. 然后继续执行线程2的m1()方法, 打印 m1(): b=1000
5. 最后执行主线程,打印 最后结果 : b=1000

应该是这样的执行结果, 但是我有一个疑问, 这样由CPU进行线程间的切换的话, 由于m1()和m2()方法都加了锁,那这两个方法在执行的时候tr这个对象应该是被锁住了啊, 既然是锁住的话,那么如果CPU从一个线程对象切换到另外一个线程对象,用的是同一个TestThread对象, 难道不会重复的加锁么? 比如从主线程的m2()切换到线程2的m1(), 那主线程的m2()加在tr上的锁怎么办?
请指教.

62,613

社区成员

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

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