Java 当我在循环中创建线程时,它是真的多线程吗
我尝试在一个10次循环中创建10个线程,并希望在我没有在方法上分配synchronized时看到冲突打印出来。 这是我的密码Java 当我在循环中创建线程时,它是真的多线程吗,java,Java,我尝试在一个10次循环中创建10个线程,并希望在我没有在方法上分配synchronized时看到冲突打印出来。 这是我的密码 public class SingletonService { private static SingletonService singleton = null; public static SingletonService getInstance() { if (singleton == null) { synchronized(Singl
public class SingletonService {
private static SingletonService singleton = null;
public static SingletonService getInstance() {
if (singleton == null) {
synchronized(SingletonService.class) {
if (singleton == null) {
singleton = new SingletonService();
return singleton;
}
}
}
return singleton;
}
public void testMethod() {
boolean flag = true;
System.out.println("start");
if (flag == false) {
System.out.println(">>>>>>>>>>>>>>>Error");
}
flag = false;
System.out.println("over");
}
}
下面是获取服务并调用testMethod()的线程
现在让我很困惑的是,当我尝试在循环中创建线程时
for (int i = 0; i < 10; i ++) {
Transferable t1 = new Transferable(service);
t1.run();
Thread.sleep(10);
}
错误信息被打印出来,开始-结束序列也变得混乱。。。
有谁能帮我解决这个问题,告诉我细节吗?
谢谢^BR您的两个示例的行为有很多原因 首先,
SingletonService.testMethod()
将flag
定义为局部变量。因此,它不能真正用作检查线程冲突的标志。我不知道你怎么会得到错误输出。此标志应该是一个字段
其次,循环示例调用线程的run()
方法,而手动示例调用start()
方法start()
将创建一个新线程,该线程将依次调用run()
方法run()
只需在current线程中执行Transferable.run()
方法,从而强制执行顺序操作
第三,如果您要更改上述内容,那么在每个循环中仍然会有一个
线程。sleep(10)
调用,这意味着在启动一个线程和下一个线程之间,等待10毫秒的时间足以让第一个线程完成。这两个示例的行为有很多原因
首先,SingletonService.testMethod()
将flag
定义为局部变量。因此,它不能真正用作检查线程冲突的标志。我不知道你怎么会得到错误输出。此标志应该是一个字段
其次,循环示例调用线程的run()
方法,而手动示例调用start()
方法start()
将创建一个新线程,该线程将依次调用run()
方法run()
只需在current线程中执行Transferable.run()
方法,从而强制执行顺序操作
第三,如果您要更改上述内容,那么每个循环中仍然会有一个
线程.sleep(10)
调用,这意味着在启动一个线程和下一个线程之间,您需要等待10毫秒,这对于第一个线程的完成来说已经足够了。请查看Thread java se文档站点
特别是start()方法
start():使该线程开始执行;Java虚拟机调用此线程的run方法
在循环中调用run()不会导致Thead执行。相反,run()是在主线程中执行的,这就是为什么执行是顺序的,而不是像您预期的那样并行
请尝试在for循环中将run()替换为start()。查看Thread java se文档站点 特别是start()方法 start():使该线程开始执行;Java虚拟机调用此线程的run方法 在循环中调用run()不会导致Thead执行。相反,run()是在主线程中执行的,这就是为什么执行是顺序的,而不是像您预期的那样并行
请尝试在for循环中将run()替换为start()。
Thread.sleep(10)代码>这是足够的时间了。你觉得手动启动线程的方式有什么不同吗,与你的循环如何运行它们相比?说实话……我怀疑循环中的线程运行只会永远执行某个线程,因为每次我只是将一个新线程指向t1……JVM将强制它在新引用开始thread.sleep(10)之前完成运行代码>这是足够的时间了。你觉得手动启动线程的方式有什么不同吗,与你的循环如何运行它们相比?说实话……我怀疑循环中的线程运行只会永远执行某个线程,因为每次我只是将一个新线程指向t1……JVM将强制它在新引用开始之前完成运行谢谢回答。但是,当我尝试手动创建线程10次而不是将其作为新线程指向时,为什么Thread.sleep(10)可以工作呢?我试图按照你的建议更新我的源代码,但仍然打印相同的结果。第一个行为是我上传代码的错误。导致此问题的原因正是第二个行为需要回答。但是,当我尝试手动创建线程10次而不是将其作为新线程指向时,为什么Thread.sleep(10)可以工作呢?我试图按照您的建议更新我的源代码,但仍然打印相同的结果。第一个行为是我上传代码的错误。导致此问题的原因正是第二个行为
for (int i = 0; i < 10; i ++) {
Transferable t1 = new Transferable(service);
t1.run();
Thread.sleep(10);
}
Transferable t1 = new Transferable(service);
Transferable t2 = new Transferable(service);
Transferable t3 = new Transferable(service);
Transferable t4 = new Transferable(service);
Transferable t5 = new Transferable(service);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();