线程没有同时运行

时间:2013-09-02 04:24:55

标签: java multithreading concurrency threadpool

我创建了一个并发类来测试线程。因为我想找到同时运行线程的最佳方法。

我对结果感到惊讶:

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;
    }

}

4 个答案:

答案 0 :(得分:2)

Thread构造函数接受RunnableThread将最终执行run()方法。现在你没有返回Runnable个对象。你回来了null。因此,您在test()otherTest()方法中执行的执行将同步执行。

所有执行都发生在一个线程中。此

new Thread(new ThreadTest().test()).start();

执行test(),睡眠一秒,打印"test"并返回nullstart()调用无效,因为Runnablenull。对于你所做的每一个电话都会继续这样做。

您需要将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)

您需要将testotherTest方法实施为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();
}