各位好~~
本人在学习线程的时候碰到一个问题
以下是代码public class Test implements Runnable{
public static Integer num = 1;
private String name;
public Test(String name){
this.name = name;
}
public void run(){
int i = 0;
try{
while(true){
System.out.println(name + ": outside");
synchronized(num){
System.out.println(name + ": entered");
if(i > 10){
break;
}
i++;
num--;
Thread.sleep(10);
System.out.println(name + ": leaved");
}
}
}catch(Exception exp){
exp.printStackTrace();
}
} public static void main(String[] args){
Test t1 = new Test("t1");
Test t2 = new Test("t2");
Thread th1 = new Thread(t1);
Thread th2 = new Thread(t2);
th1.start();
th2.start();
}
}输出结果为
t1: outside
t1: entered
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
为什么当t1线程在同步块里的时候,t2也可以进来啊?如果我把 num--; 这句注释掉就没有这个问题
谁能告诉我这是为什么啊???谢谢
本人在学习线程的时候碰到一个问题
以下是代码public class Test implements Runnable{
public static Integer num = 1;
private String name;
public Test(String name){
this.name = name;
}
public void run(){
int i = 0;
try{
while(true){
System.out.println(name + ": outside");
synchronized(num){
System.out.println(name + ": entered");
if(i > 10){
break;
}
i++;
num--;
Thread.sleep(10);
System.out.println(name + ": leaved");
}
}
}catch(Exception exp){
exp.printStackTrace();
}
} public static void main(String[] args){
Test t1 = new Test("t1");
Test t2 = new Test("t2");
Thread th1 = new Thread(t1);
Thread th2 = new Thread(t2);
th1.start();
th2.start();
}
}输出结果为
t1: outside
t1: entered
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
t1: leaved
t1: outside
t1: entered
t2: leaved
t2: outside
t2: entered
为什么当t1线程在同步块里的时候,t2也可以进来啊?如果我把 num--; 这句注释掉就没有这个问题
谁能告诉我这是为什么啊???谢谢
解决方案 »
- java能做语音通讯的软件吗?像QQ语音聊天那样!
- '水仙花数'怎么求????
- 精典的java题目!
- 谈谈你对“面向对象”的高见?
- 数组问题
- 求教:怎样用JAVA做可视化设计器?
- 想学j2ee,各位ggjj给点建议,小弟不胜感激!!!
- bool值:10 > 5 && 1 > 0 || 3 > 5 || 20 == 8
- 如何格式一个字符串(请求帮助)(分数不够可以加
- 我是搞C++的!现在想搞JAVA!于是想问: JDK, JSDK ,JRE ,它们是搞什么作用的,难道它没有像C++那样有集成环境吗,还有.......(内容)
- 奇怪!大家来看看究竟!
- 求助JAVA高手:用JAVA实现填充任意多边形的算法!
Test t2 = new Test("t2");
Thread th1 = new Thread(t1);
Thread th2 = new Thread(t2); 你同步了什么东西?2个线程自己玩自己的,输出是随机。
num--
这句相当于:
num = num - 1;
这里有自动拆箱和装箱的动作,首先,原来的num被拆成一个一般的int,用它跟1相减,然后其结果再被重新装箱成“另一个”Integer对象赋给静态变量num。说起来好像挺复杂,但对你的问题而言,不需要知道那么多,只需要明白一点,经过“num--”之后,num变量就不再引用原来的那个对象了,这就使得两个线程完全可能开始在两个不同的对象上进行synchonized,于是它们也就互不干涉,互不影响,这也是为什么注释掉这句就没有问题的原因。在这种情形下,如果要避免产生这种问题,可以考虑将num定义成static final的,那样的话,就不能进行“--”了(编译会帮你提示错误)。如果确实需要“--”,就只能靠细心了。不过至少也应记住,自动装箱/拆箱要慎用,否则弄出问题,半天调试不出原因出在哪里。
比如:
String s = ...;
s += ...
后面这句看起来挺无辜的,实质上也是相当于:
s = s + ...;
如果用在楼主的例子中,也同样会出现令人奇怪的结果。
所以,只要是非内建类型在而且支持除"="以外的赋值,不管是由于装箱拆箱,还是由于本来就支持,用得时候都得细心一点。如果出了令人奇怪的问题,也尽量先想想这些方面。