让线程睡眠不同的时间

时间:2014-03-29 13:39:25

标签: java multithreading

我应该首先创建3个线程,每3秒打印一次'A',每4秒打印一次'B',每5秒打一次'C'

我是这样做的,但他们改变了他们的印刷顺序,这是可疑的。但我认为,在第9秒他们可以混合...和它的罚款。请发表你的意见。

public class MyThread extends Thread {

    static int ID;
    int id;

    public MyThread() {
        id = ID++;
    }

    public synchronized void run() {
        char character = (char) (65 + id);
        while (true) {
            System.out.println(character);
            try {
                Thread.sleep(3000 + id * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        new MyThread().start();
        new MyThread().start();
        new MyThread().start();
    }
}

输出:

A
B
C
A
B
C
A
B
A
C
B
A
.......

2 个答案:

答案 0 :(得分:2)

使用sleep时存在一般问题;它安排在一个任务的结束和下一个任务的开始之间。两个任务开始之间

因此,每次你的任务运行时,它们都会让你的运行时间稍微偏离。

这通常是sleep未用于按特定比率安排任务的原因。

正如@Joachim指出的那样,你的输出看起来很好。这是一个快速计算每个线程应该打印的时间:

Timeline spreadsheet

但我强烈建议您使用ScheudledExecutorService,如下所示:

public static void main(final String[] args) throws Exception {
    final ScheduledExecutorService ses = Executors.newScheduledThreadPool(3);
    final class Work implements Runnable {

        private final String name;

        public Work(String name) {
            this.name = name;
        }

        @Override
        public void run() {
            System.out.println(name);
        }
    }
    ses.scheduleAtFixedRate(new Work("A"), 0, 3, TimeUnit.SECONDS);
    ses.scheduleAtFixedRate(new Work("B"), 0, 4, TimeUnit.SECONDS);
    ses.scheduleAtFixedRate(new Work("C"), 0, 5, TimeUnit.SECONDS);
    ses.schedule(new Runnable() {

        @Override
        public void run() {
            ses.shutdown();
        }
    }, 1, TimeUnit.MINUTES);
    ses.awaitTermination(1, TimeUnit.DAYS);
}

使用一些Java 8 lambdas:

public static void main(final String[] args) throws Exception {
    final ScheduledExecutorService ses = Executors.newScheduledThreadPool(3);
    ses.scheduleAtFixedRate(() -> System.out.println("A"), 0, 3, TimeUnit.SECONDS);
    ses.scheduleAtFixedRate(() -> System.out.println("B"), 0, 4, TimeUnit.SECONDS);
    ses.scheduleAtFixedRate(() -> System.out.println("C"), 0, 5, TimeUnit.SECONDS);
    ses.schedule(() -> ses.shutdown(), 1, TimeUnit.MINUTES);
    ses.awaitTermination(1, TimeUnit.DAYS);
}

答案 1 :(得分:1)

评论中讨论的样式问题除外,您显示的输出看起来是正确的;

A    0 seconds, thread start
B    0 seconds, thread start
C    0 seconds, thread start
A    3 seconds
B    4 seconds
C    5 seconds
A    6 seconds (2*3)
B    8 seconds (2*4)
A    9 seconds (3*3)
C   10 seconds (2*5)
B   12 seconds (3*4)
A   12 seconds (4*3)
...