我创建了一个并发类来测试线程。因为我想找到同时运行线程的最佳方法。
我对结果感到惊讶:
test
test
Othertest
test
Othertest
test
test
test
我预期的结果是线程随机返回,但它们似乎以相同的顺序一致地返回!有谁知道为什么?这是否意味着他们没有同时运行?我怎么能让它们同时运行呢?
这是我的代码:
public class ThreadTest {
public static void main(String args[]) throws InterruptedException
{
new Thread(new ThreadTest().test()).start();
new Thread(new ThreadTest().test()).start();
new Thread(new ThreadTest().otherTest()).start();
new Thread(new ThreadTest().test()).start();
new Thread(new ThreadTest().otherTest()).start();
new Thread(new ThreadTest().test()).start();
new Thread(new ThreadTest().test()).start();
new Thread(new ThreadTest().test()).start();
}
public Runnable test() throws InterruptedException{
Thread.sleep((long) (Math.random()*1000));
System.out.println("test");
return null;
}
public Runnable otherTest() throws InterruptedException{
Thread.sleep((long) (Math.random()*1000));
System.out.println("Othertest");
return null;
}
}
答案 0 :(得分:2)
Thread
构造函数接受Runnable
,Thread
将最终执行run()
方法。现在你没有返回Runnable
个对象。你回来了null
。因此,您在test()
和otherTest()
方法中执行的执行将同步执行。
所有执行都发生在一个线程中。此
new Thread(new ThreadTest().test()).start();
执行test()
,睡眠一秒,打印"test"
并返回null
。 start()
调用无效,因为Runnable
为null
。对于你所做的每一个电话都会继续这样做。
您需要将test()
和otherTest()
方法中的所有内容放在Runnable#run()
方法中。例如
new Thread(new Runnable() {
public void run() {
Thread.sleep((long) (Math.random()*1000));
System.out.println("test");
}
}).start();
考虑run()
类的Thread
方法的源代码,该方法在调用start()
时执行
@Override
public void run() {
if (target != null) {
target.run();
}
}
target
是您在构造函数中传递的Runnable
引用。显然,如果它是null
,它将不会做任何事情。
答案 1 :(得分:1)
您的Thread
实施错误。
您应该实施Runnable
并实施run()
方法或
您应该扩展Thread
类并覆盖run()
方法。
正在发生的事情是,您正在调用test()
方法或otherTest()
,就像任何方法调用一样。由于您没有任何run()
方法,因此Thread.start()
不会简单地运行任何内容。
尝试更改您的方法,如下所示。
public Runnable test() {
return new Runnable() {
@Override
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("test");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
public Runnable otherTest() {
System.out.println("Othertest");
return new Runnable() {
@Override
public void run() {
try {
Thread.sleep((long) (Math.random() * 1000));
System.out.println("Othertest");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
};
}
答案 2 :(得分:1)
我想你可能会有更好的运气:
public class ThreadTest {
public static void main(String args[]) throws InterruptedException
{
new Thread(test).start();
new Thread(test).start();
new Thread(otherTest).start();
new Thread(test).start();
new Thread(otherTest).start();
new Thread(test).start();
new Thread(test).start();
new Thread(test).start();
}
public static Runnable test = new Runnable() {
@Override
public void run() {
try {
Thread.sleep((long) (Math.random()*1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("test");
}
};
public static Runnable otherTest = new Runnable() {
@Override
public void run(){
try {
Thread.sleep((long) (Math.random()*1000));
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("Othertest");
}
};
}
我们的想法是将Runnable
的实例作为参数传递给Thread
构造函数。您并没有真正这样做,因为test()
和otherTest()
都返回null
。上面的代码显示了一种以我猜你想要的方式运行线程的方法。其他方法肯定是可能的。
答案 3 :(得分:1)
您需要将test
和otherTest
方法实施为Runnable
实施。像这样:
private static class Test implements Runnable {
@Override
public void run() {
try {
Thread.sleep((long) (Math.random()*1000));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
System.out.println("test");
}
}
private static class OtherTest implements Runnable {
@Override
public void run() {
try {
Thread.sleep((long) (Math.random()*1000));
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return;
}
System.out.println("Othertest");
}
}
public static void main(String args[]) {
new Thread(new Test()).start();
new Thread(new Test()).start();
new Thread(new OtherTest()).start();
new Thread(new Test()).start();
new Thread(new OtherTest()).start();
new Thread(new Test()).start();
new Thread(new Test()).start();
new Thread(new Test()).start();
}
当然,您可以尝试减少重复:
private enum Runnables implements Runnable {
TEST {
@Override
public void run() {
if (!sleep()) return;
System.out.println("test");
}
},
OTHER_TEST {
@Override
public void run() {
if (!sleep()) return;
System.out.println("Othertest");
}
};
static boolean sleep() {
try {
Thread.sleep((long) (Math.random()*1000));
return true;
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
return false;
}
}
}
public static void main(String args[]) {
new Thread(Runnables.TEST).start();
new Thread(Runnables.TEST).start();
new Thread(Runnables.OTHER_TEST).start();
new Thread(Runnables.TEST).start();
new Thread(Runnables.OTHER_TEST).start();
new Thread(Runnables.TEST).start();
new Thread(Runnables.TEST).start();
new Thread(Runnables.TEST).start();
}