问题描述
我想问问通过extends方法创建的多线程对象1它们操作的是不是同一个单例方法?是的话那如果在一开始判断的时候线程切换了,会不会出现2个线程都判断null而产生2个对象?我试了挺多次都是同一个对象..难道线程有运行先后之分吗?publicclassDemo6{publicstaticvoidmain(String[]args){ThreadTestt1=newThreadTest();ThreadTestt2=newThreadTest();t1.start();t2.start();}}classThreadTestextendsThread{@Overridepublicvoidrun(){for(inti=0;i<50;i++){InstanceDemo.getInstance();//重写线程父类run方法}}}classInstanceDemo{//首先你得写一个单例模式privateInstanceDemo(){}//私有化构造函数privatestaticInstanceDemoinstance;//这里用的是懒汉式所以只是声明//然后提供一个对外提供唯一实例的方法publicstaticInstanceDemogetInstance(){if(instance==null){instance=newInstanceDemo();}System.out.println(Thread.currentThread().getName()+instance);returninstance;}}
解决方案
解决方案二:
1、线程同步,将getInstance方法加上synchrolize关键字2、线程运行没有先后之分,你的这种情况只是偶然吧
解决方案三:
我可能想明白了。通过extends操作的不是同一份资源,但是如果是单例模式的话某种意义上说就相当于是操作同一份资源了,所以它们还是会有可能出现问题的,在sleep方法之后就有可能出现问题的否则几率极低。不知道我的理解有没问题望指点!
解决方案四:
你的代码写的是有问题的,并不能保证绝对单例。可以将实例化放到static块中,或者将getInstance进行同步控制。
解决方案五:
1、是肯定的,必定是操作同一个getInstance()方法。2、理论上有可能两个线程都判断到instance==null的情况。3、线程运行当然有先后之分了,只不过这个先后顺序由CPU统一去调度,我们一般无法控制,且某线程正在运行时,CPU可能会先暂停该线程而去运行其它的线程。
解决方案六:
如果你用10个甚至更多的线程去跑的话,并且在getInstance方法内sleep一段时间,就会发生创建多个实例的情况了亲自跑过publicclassDemo6{publicstaticvoidmain(String[]args){//ThreadTestt1=newThreadTest();//ThreadTestt2=newThreadTest();////t1.start();//t2.start();for(inti=0;i<10;i++){ThreadTestt1=newThreadTest();t1.start();}}}classThreadTestextendsThread{@Overridepublicvoidrun(){for(inti=0;i<50;i++){InstanceDemo.getInstance();//重写线程父类run方法}}}classInstanceDemo{//首先你得写一个单例模式privateInstanceDemo(){}//私有化构造函数privatestaticInstanceDemoinstance;//这里用的是懒汉式所以只是声明//然后提供一个对外提供唯一实例的方法publicstaticInstanceDemogetInstance(){if(instance==null){try{Thread.sleep(1000);//为了更容易发生}catch(InterruptedExceptione){//TODOAuto-generatedcatchblocke.printStackTrace();}instance=newInstanceDemo();}System.out.println(Thread.currentThread().getName()+instance);returninstance;}}
结果至少创建了三个实例Thread-3com.zp.threadtest.InstanceDemo@8813f2Thread-7com.zp.threadtest.InstanceDemo@83cc67Thread-1com.zp.threadtest.InstanceDemo@8813f2Thread-8com.zp.threadtest.InstanceDemo@83cc67Thread-8com.zp.threadtest.InstanceDemo@83cc67Thread-8com.zp.threadtest.InstanceDemo@83cc67Thread-8com.zp.threadtest.InstanceDemo@83cc67Thread-8com.zp.threadtest.InstanceDemo@83cc67Thread-8com.zp.threadtest.InstanceDemo@83cc67Thread-8com.zp.threadtest.InstanceDemo@83cc67Thread-8com.zp.threadtest.InstanceDemo@83cc67Thread-8com.zp.threadtest.InstanceDemo@83cc67Thread-8com.zp.threadtest.InstanceDemo@83cc67Thread-8com.zp.threadtest.InstanceDemo@83cc67Thread-8com.zp.threadtest.InstanceDemo@83cc67Thread-8com.zp.threadtest.InstanceDemo@e09713Thread-8com.zp.threadtest.InstanceDemo@e09713Thread-8com.zp.threadtest.InstanceDemo@e09713Thread-8com.zp.threadtest.InstanceDemo@e09713
解决方案七:
publicstaticInstanceDemogetInstance(){if(instance==null){synchronized(instance){if(instance==null){instance=newInstanceDemo();}}}System.out.println(Thread.currentThread().getName()+instance);returninstance;}
这样写就不会出现实例化两个以上对象的情况了其他的问题楼上也已有回答,但是关于线程的先后之分这个问题,我觉得楼上的回答都不正确,这个可以分为时间上的先后和执行顺序上的先后去讨论,而后者是可以通过同步去控制的。鄙人也是菜鸟一枚,在这里就不多说了