问题描述
publicclassMyThreadextendsThread{privatestaticintcount=0;publicsynchronizedvoidrun(){for(inti=0;i<10;i++){count=count+1;System.out.println(getName()+""+count);}}publicMyThread(Stringthread){super(thread);}/***@paramargs*/publicstaticvoidmain(String[]args){//TODO自动生成方法存根MyThreadt1=newMyThread("t1");MyThreadt2=newMyThread("t2");t1.start();//try{//sleep(100);//}catch(InterruptedExceptione){}t2.start();}}代码很简单,我创建了t1t2两个线程,想让他们互斥的访问run函数,但是运行的时候顺序总是不对,除非用个sleep到底怎么回事啊?
解决方案
解决方案二:
你是想t1先运行,t2后运行是吧对于线程,t1和t2总是互相争夺cpu资源的,即使你先t1.start()
解决方案三:
privatestaticObjectlock=newObject();publicvoidrun(){synchronized(lock){for(inti=0;i<10;i++){count=count+1;System.out.println(getName()+""+count);}}}
解决方案四:
t1和t2是不会互斥访问run函数的。你要搞清楚一个概念,synchronized关键字同步的不是同一段代码,而是同一个对象。而t1和t2是两个对象,因此,当t1执行run函数的时候,根本不妨碍t2也去执行run函数,因为t1和t2是两个对象嘛。
解决方案五:
引用3楼westlifejxb的回复:
t1和t2是不会互斥访问run函数的。你要搞清楚一个概念,synchronized关键字同步的不是同一段代码,而是同一个对象。而t1和t2是两个对象,因此,当t1执行run函数的时候,根本不妨碍t2也去执行run函数,因为t1和t2是两个对象嘛。
是的,如果LZ在run中sleep一会儿就更显而易见了publicsynchronizedvoidrun(){for(inti=0;i<10;i++){count=count+1;try{sleep(100);}catch(InterruptedExceptione){}System.out.println(getName()+""+count);}}
解决方案六:
synchronized是一个对象当前执行的同步方法结束后,该对象的另一个同步方法才可以执行。
解决方案七:
引用3楼westlifejxb的回复:
t1和t2是不会互斥访问run函数的。你要搞清楚一个概念,synchronized关键字同步的不是同一段代码,而是同一个对象。而t1和t2是两个对象,因此,当t1执行run函数的时候,根本不妨碍t2也去执行run函数,因为t1和t2是两个对象嘛。
谢谢,但是我还有一个疑问,既然这样,那么synchronized修饰函数的作用是什么呢?
解决方案八:
该回复于2011-03-28 08:57:46被版主删除
解决方案九:
难道楼主想写的是死锁的问题?
解决方案十:
引用6楼aoyuehan11的回复:
引用3楼westlifejxb的回复:t1和t2是不会互斥访问run函数的。你要搞清楚一个概念,synchronized关键字同步的不是同一段代码,而是同一个对象。而t1和t2是两个对象,因此,当t1执行run函数的时候,根本不妨碍t2也去执行run函数,因为t1和t2是两个对象嘛。谢谢,但是我还有一个疑问,既然这样,那么synchronized修饰函数的作用是什么呢?……
修饰实例方法使用对象的监视器,进行同步,如果有多个实例方法都是synchronized,则同一时刻,只能有一个方法在运行
解决方案十一:
加锁!!!让没有用的资源等待在用的资源结束使用后在申请使用
解决方案十二:
哦,我懂了,synchronized方法是为了让一个对象互斥的访问多个synchronized方法的,不是让多个对象互斥的访问这一个synchronized方法的。当synchronized修饰一个方法时,锁住的对象是this,总是调用这个方法的对象本身,对于多个对象来说,它们就互不影响了。其实,想要多个对象互斥的访问run方法,就该不用synchronized修饰这个方法,而是用synchronized(MyThread.class)块来修饰for循环,这样锁住的是MyThread.class,从java的反射机制将,MyThread.class就是当前调用run的对象,上锁后,只有拥有这个对象的线程才能进入run
解决方案十三:
引用1楼singwhatiwanna的回复:
你是想t1先运行,t2后运行是吧对于线程,t1和t2总是互相争夺cpu资源的,即使你先t1.start()
同意1L的说法。。
解决方案十四:
MyThreadt1=newMyThread("t1");MyThreadt2=newMyThread("t2");不是同一个对象的线程!TestThredth=newTestThread();newThread(th).start();newThread(th).start();这样才能互斥!
解决方案十五:
synchronized在你这例子中几乎是没用,此方法只能保证在同一个实例中多线程调此方法时有用。