关于通过extends实现的多线程疑问 多线程threadjava实例 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 1、线程同步,将getInstance方法加上synchrolize关键字2、线程运行没有先后之分,你的这种情况只是偶然吧 我可能想明白了。通过extends操作的不是同一份资源,但是如果是单例模式的话某种意义上说就相当于是操作同一份资源了,所以它们还是会有可能出现问题的,在 sleep方法之后就有可能出现问题的 否则几率极低。不知道我的理解有没问题 望指点! 你的代码写的是有问题的,并不能保证绝对单例。可以将实例化放到static块中,或者将getInstance进行同步控制。 1、是肯定的,必定是操作同一个getInstance()方法。2、理论上有可能两个线程都判断到instance==null的情况。3、线程运行当然有先后之分了,只不过这个先后顺序由CPU统一去调度,我们一般无法控制,且某线程正在运行时,CPU可能会先暂停该线程而去运行其它的线程。 如果你用10个甚至更多的线程去跑的话,并且在getInstance方法内sleep一段时间,就会发生创建多个实例的情况了亲自跑过public class Demo6 { public static void main(String[] args) { // ThreadTest t1=new ThreadTest(); // ThreadTest t2=new ThreadTest(); // // t1.start(); // t2.start(); for (int i = 0; i < 10; i++) { ThreadTest t1 = new ThreadTest(); t1.start(); } }}class ThreadTest extends Thread { @Override public void run() { for (int i = 0; i < 50; i++) { InstanceDemo.getInstance();// 重写线程父类run方法 } }}class InstanceDemo {// 首先你得写一个单例模式 private InstanceDemo() { }// 私有化构造函数 private static InstanceDemo instance; // 这里用的是懒汉式 所以只是声明 // 然后提供一个对外提供唯一实例的方法 public static InstanceDemo getInstance() { if (instance == null) { try { Thread.sleep(1000);//为了更容易发生 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } instance = new InstanceDemo(); } System.out.println(Thread.currentThread().getName() + instance); return instance; }}结果至少创建了三个实例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 public static InstanceDemo getInstance(){ if(instance==null){ synchronized(instance){ if(instance==null){ instance=new InstanceDemo(); } } } System.out.println(Thread.currentThread().getName()+instance); return instance;}这样写就不会出现实例化两个以上对象的情况了其他的问题楼上也已有回答,但是关于线程的先后之分这个问题,我觉得楼上的回答都不正确,这个可以分为时间上的先后和执行顺序上的先后去讨论,而后者是可以通过同步去控制的。鄙人也是菜鸟一枚,在这里就不多说了 j2ee学习流程和功能 关于for与while的问题 控制台输出“使用或覆盖了已过时的 API。”是怎么回事啊。跪求解答 JAVA程序的运行 请问哪里有JMF的API文档? 菜鸟问题,请大哥执教,来者有分! 在java程序中如何启动另一个应用程序,即如何调用其他的exe文件? 在WIN98下JDK1.4如何设置? 什么是逆序树! 求点拨一个“特奇葩”的代码报错。 关于排序 不同平台下JDK JRE JVM 的区别
2、线程运行没有先后之分,你的这种情况只是偶然吧
通过extends操作的不是同一份资源,但是如果是单例模式的话某种意义上说就相当于是操作同一份资源了,所以它们还是会有可能出现问题的,在 sleep方法之后就有可能出现问题的 否则几率极低。
不知道我的理解有没问题 望指点!
2、理论上有可能两个线程都判断到instance==null的情况。
3、线程运行当然有先后之分了,只不过这个先后顺序由CPU统一去调度,我们一般无法控制,且某线程正在运行时,CPU可能会先暂停该线程而去运行其它的线程。
亲自跑过public class Demo6 {
public static void main(String[] args) {
// ThreadTest t1=new ThreadTest();
// ThreadTest t2=new ThreadTest();
//
// t1.start();
// t2.start(); for (int i = 0; i < 10; i++) {
ThreadTest t1 = new ThreadTest();
t1.start();
}
}
}class ThreadTest extends Thread {
@Override
public void run() {
for (int i = 0; i < 50; i++) {
InstanceDemo.getInstance();// 重写线程父类run方法
}
}
}class InstanceDemo {// 首先你得写一个单例模式
private InstanceDemo() {
}// 私有化构造函数 private static InstanceDemo instance; // 这里用的是懒汉式 所以只是声明 // 然后提供一个对外提供唯一实例的方法
public static InstanceDemo getInstance() {
if (instance == null) {
try {
Thread.sleep(1000);//为了更容易发生
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
instance = new InstanceDemo();
}
System.out.println(Thread.currentThread().getName() + instance);
return instance;
}
}
结果至少创建了三个实例
Thread-3com.zp.threadtest.InstanceDemo@8813f2
Thread-7com.zp.threadtest.InstanceDemo@83cc67
Thread-1com.zp.threadtest.InstanceDemo@8813f2
Thread-8com.zp.threadtest.InstanceDemo@83cc67
Thread-8com.zp.threadtest.InstanceDemo@83cc67
Thread-8com.zp.threadtest.InstanceDemo@83cc67
Thread-8com.zp.threadtest.InstanceDemo@83cc67
Thread-8com.zp.threadtest.InstanceDemo@83cc67
Thread-8com.zp.threadtest.InstanceDemo@83cc67
Thread-8com.zp.threadtest.InstanceDemo@83cc67
Thread-8com.zp.threadtest.InstanceDemo@83cc67
Thread-8com.zp.threadtest.InstanceDemo@83cc67
Thread-8com.zp.threadtest.InstanceDemo@83cc67
Thread-8com.zp.threadtest.InstanceDemo@83cc67
Thread-8com.zp.threadtest.InstanceDemo@83cc67
Thread-8com.zp.threadtest.InstanceDemo@e09713
Thread-8com.zp.threadtest.InstanceDemo@e09713
Thread-8com.zp.threadtest.InstanceDemo@e09713
Thread-8com.zp.threadtest.InstanceDemo@e09713
if(instance==null){
synchronized(instance){
if(instance==null){
instance=new InstanceDemo();
}
}
}
System.out.println(Thread.currentThread().getName()+instance);
return instance;
}
这样写就不会出现实例化两个以上对象的情况了
其他的问题楼上也已有回答,但是关于线程的先后之分这个问题,我觉得楼上的回答都不正确,这个可以分为时间上的先后和执行顺序上的先后去讨论,而后者是可以通过同步去控制的。鄙人也是菜鸟一枚,在这里就不多说了