0

我做了一个并发类来测试线程。因为我想找出同时运行线程的最佳方式。

我对我的结果感到惊讶:

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

4 回答 4

2

Thread构造函数接受最终将在其上执行方法Runnable的a。现在你没有返回一个对象。你回来了。因此,您在和方法中执行的操作是同步执行的。Threadrun()Runnablenulltest()otherTest()

您的所有执行都发生在一个线程中。这

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

执行test(),休眠一秒钟,打印"test"并返回nullstart()调用没有做任何事情,因为Runnableis 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,它不会做任何事情。

于 2013-09-02T04:29:24.090 回答
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();
            }
        }
    };
}
于 2013-09-02T04:28:08.463 回答
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。上面的代码显示了一种以我猜你想要的方式运行线程的方法。其他方法当然是可能的。

于 2013-09-02T04:34:11.190 回答
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();
}
于 2013-09-02T04:35:58.603 回答