新手第一次发帖,关于线程,求解答

风萧萧2016 2015-09-08 10:00:50
class ThreadTest2 
{
public static void main(String[] args)
{
new Thread(new Thread1("Thread1")).start();
new Thread(new Thread1("Thread2")).start();
}
}

class Thread1 implements Runnable
{
private String name;
private static int tit = 100;

public Thread1(String name) {
this.name = name;
}

public String getName(){
return this.name;
}

public void run() {
while(tit>0) {
synchronized(new Object()) {
System.out.println(this.getName()+"___"+tit--);
}
}
}
}


为什么最后输出那行会不按序输出,求解答,谢谢!
...全文
133 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
解开者 2015-09-08
  • 打赏
  • 举报
回复
synchronized(new Object()) 这个同步块是不好用的,因为tit是类成员,同步块要synchronized(Thread1.class)才能工作 所以上边的代码就不是同步的,线程可能在执行System.out.println(this.getName()+"___"+tit--)的过程中被调度走。 楼主可以试试多建几个线程,控制台输出的末尾一定是每个线程输出一行,输出的数字就是线程最后一次被调度时tit的值。
wula0010 2015-09-08
  • 打赏
  • 举报
回复
线程的执行是分时抢占执行的,先生成的线程,未必能先抢占到cpu先执行,所以会这样..............
风萧萧2016 2015-09-08
  • 打赏
  • 举报
回复
运行多次都是最后一行出问题,实在是想不出来,不是进入一线程进入同步内的时候不出来其他线程是进不去的吗,也就是不打印其他线程就执行不了啊。而且怎么出问题都是在最后一行出啊?希望知道的人解答一下,感激~
风萧萧2016 2015-09-08
  • 打赏
  • 举报
回复
引用 5 楼 luoyuehao 的回复:
new object()那个地方,没有同步到,每次都new object,这里的预计的同步功能没有发生作用。
恩,我懂了,感谢你的回答,不过已经结贴了,没分了
风萧萧2016 2015-09-08
  • 打赏
  • 举报
回复
引用 6 楼 windowsoahil 的回复:
同步块的原理是调用括号中对象的对象锁,产生的效果是保证只有一个线程持有该对象的锁。在某个线程进入同步块时,首先请求括号中对象的对象锁,如果没被任何线程持有,那该线程获得锁直到同步块执行结束;否则该线程进入阻塞。 要点是锁对象引用的作用域。你每次都new一个新对象,每个线程都有一个自己的对象引用并且只有它自己能获得该引用,这显然不起作用。因为需要加锁的对象是一个类成员,并且还是一个基本类型,所以不能用它本身作为锁对象,只好用它所在类的Class对象。
嗯嗯,解释的很详细, 完全懂了,在类中new一个静态Object也是解决了问题,灰常感谢~
解开者 2015-09-08
  • 打赏
  • 举报
回复
同步块的原理是调用括号中对象的对象锁,产生的效果是保证只有一个线程持有该对象的锁。在某个线程进入同步块时,首先请求括号中对象的对象锁,如果没被任何线程持有,那该线程获得锁直到同步块执行结束;否则该线程进入阻塞。 要点是锁对象引用的作用域。你每次都new一个新对象,每个线程都有一个自己的对象引用并且只有它自己能获得该引用,这显然不起作用。因为需要加锁的对象是一个类成员,并且还是一个基本类型,所以不能用它本身作为锁对象,只好用它所在类的Class对象。
罗键键 2015-09-08
  • 打赏
  • 举报
回复
new object()那个地方,没有同步到,每次都new object,这里的预计的同步功能没有发生作用。
风萧萧2016 2015-09-08
  • 打赏
  • 举报
回复
引用 3 楼 windowsoahil 的回复:
synchronized(new Object()) 这个同步块是不好用的,因为tit是类成员,同步块要synchronized(Thread1.class)才能工作 所以上边的代码就不是同步的,线程可能在执行System.out.println(this.getName()+"___"+tit--)的过程中被调度走。 楼主可以试试多建几个线程,控制台输出的末尾一定是每个线程输出一行,输出的数字就是线程最后一次被调度时tit的值。
虽然还是不太懂同步块的那个条件是干什么用的,但按照你说的,确实是线程同步了,可能还没有学全线程同步的内容,自己在继续学看看吧,非常感谢你的解答~

50,639

社区成员

发帖
与我相关
我的任务
社区描述
Java相关技术讨论
javaspring bootspring cloud 技术论坛(原bbs)
社区管理员
  • Java相关社区
  • 小虚竹
  • 谙忆
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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