【发布时间】:2015-08-22 08:35:26
【问题描述】:
我有一个四核 CPU。我创建了 4 个线程并运行了一个 cpu 密集型循环,它比在一个线程中以程序方式运行它所花费的时间 > 4 倍。
我创建了两个项目进行比较,一个有线程,一个没有。我将展示代码和运行时间。请注意没有线程的项目看起来很奇怪的原因是我想复制内存开销,因为我不确定它会对运行时间产生多大影响。所以,这里是没有线程的代码:
class TimeTest implements Runnable {
private Thread t;
private String name;
TimeTest(String name) {
this.name = name;
System.out.println("Creating class " + name);
}
public void run() {
System.out.println("Running class " + name);
int value = 100000000;
// try {
while (--value > 0) {
Math.random();
// Thread.sleep(1);
// System.out.println("Class " + name + " " + value);
}
// } catch (InterruptedException e) {
// System.out.println("Interrupted " + name);
// }
System.out.println("Class " + name + " exiting...");
}
public void start() {
System.out.println("Starting class " + name);
if (t == null) {
t = new Thread(this, name);
// t.start();
this.run();
}
}
}
public class ThreadComp {
public static void main(String[] args) {
TimeTest one = new TimeTest("Class-1");
one.start();
TimeTest two = new TimeTest("Class-2");
two.start();
TimeTest three = new TimeTest("Class-3");
three.start();
TimeTest four = new TimeTest("Class-4");
four.start();
}
}
这将在大约 11 秒内运行。
这是带有线程的代码:
class RunnableTest implements Runnable {
private Thread t;
private String name;
RunnableTest(String name) {
this.name = name;
System.out.println("Creating thread " + name);
}
public void run() {
System.out.println("Running thread " + name);
int value = 100000000;
// try {
while (--value > 0) {
Math.random();
// Thread.sleep(1);
// System.out.println("Thread " + name + " " + value);
}
// } catch (InterruptedException e) {
// System.out.println("Interrupted " + name);
// }
System.out.println("Thread " + name + " exiting...");
}
public void start() {
System.out.println("Starting thread " + name);
if (t == null) {
t = new Thread(this, name);
t.start();
}
}
}
public class ThreadTest {
public static void main(String[] args) {
RunnableTest one = new RunnableTest("Thread-1");
one.start();
RunnableTest two = new RunnableTest("Thread-2");
two.start();
RunnableTest three = new RunnableTest("Thread-3");
three.start();
RunnableTest four = new RunnableTest("Thread-4");
four.start();
}
}
这运行大约需要 1 分 13 秒。
现在,在我学习的示例中,他们在引导期间调用 Thread.sleep 50 毫秒。如果我这样做,如果我还在非线程类上调用 Thread.sleep(50),线程运行得更快。
这太棒了,我知道如何让它发挥作用。但是我学习这个的原因是我正在寻找路径,并且我不会在已经需要很长时间并且不需要暂停甚至 1ms 什么也不做的事情上添加睡眠调用(除非它绝对必须)。
所以,我想知道我错过了什么?线程是否绝对必须进入睡眠状态,或者对象是否必须等待它们才能按我的意图工作(即并行运行所有四个循环)?
即使我只是犯了一个错误,为什么要花这么长时间?我认为最坏的情况是,它仍然会在 11 秒内运行,它会以某种不可预见的顺序完成......
【问题讨论】:
-
那么 - 4 个女性需要 36 个月才能生下一个孩子?
-
我几乎可以保证
Math.random的使用是这个问题的原因。见docs.oracle.com/javase/8/docs/api/java/lang/Math.html#random-- -
^^ @JAtkin 说的。您的代码基本上都是锁争用。
-
@bayou.io - 我想你的意思是问是否需要 9 个女性 1 个月才能生一个孩子......
标签: java multithreading concurrency parallel-processing