如何在Java时间内同步线程

时间:2015-03-22 18:37:24

标签: java multithreading

我研究一个线程并尝试使用线程制作一个计时器。给主线程写了一段时间

public class A {
    public static void main(String[] args) throws IOException{
        BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
        System.out.println("Please, write the time in ms");
        long time = Long.parseLong(reader.readLine());
        B thread = new B();

        int timer = 0;
        try {
            thread.start();
            Thread.sleep(time);
            timer=thread.stop();
        }
        catch(InterruptedException e) {
            System.out.println("Oh....");
        }
        System.out.println("Result is "+timer);
    }
}

并且每个毫秒程序在子线程中写入特定毫秒的名称。

public class B implements Runnable {

    private volatile boolean running=true;
    private int timer=0;
    Thread thread;

    public B() {
        thread = new Thread(this);
    }

    public void run() {
        while (running) {
            System.out.println(timer);
            timer++;
        try  {
            Thread.sleep(1);
        }
        catch(InterruptedException e)  {
            System.out.println("B");
        }
        }
    }
   public int stop() {
    running = false;
    return timer;
   }

    public void start() {
        thread.start();
    }
}

但是当尝试使用参数50得到结果37.我想了解如何在时间中同步它。你能解释我怎么做对吗?

2 个答案:

答案 0 :(得分:1)

当时间结束时,只需将变量running设置为false,它将结束while循环,子线程也将完成。

所以在下面的行之后,尝试将running变量设置为false。(提供一些setter方法或者可能在构造函数参数中)

Thread.sleep(time);

答案 1 :(得分:0)

您忘记了Thread.sleep(1)以外的所有语句也需要时间来执行。最值得注意的是System.out.println(timer):这是一个I / O操作,每当发生这样的操作时,它通常会耗费时间(打印到屏幕会使程序等待此阻塞I / O操作完成)。

但我想展示一个更微妙的假设:你还假设当thread.start()返回时,B.run()正在执行。情况并非如此,正如以下小程序所示:

import java.util.concurrent.TimeUnit;

public class ThreadTimer implements Runnable {

    public static void main(String[] args) {

        ThreadTimer tt = new ThreadTimer();
        long afterStart = 0L;
        new Thread(tt).start();
        afterStart = System.nanoTime();
        println("After start: " + afterStart);
        try {
            Thread.sleep(100L);
        } catch (Exception e) {
            e.printStackTrace();
        }
        long deltaStart = tt.realStart - afterStart;
        println("Delta start: " + deltaStart);
        long deltaStartMs = TimeUnit.NANOSECONDS.toMillis(deltaStart);
        println("Delta start ms.: " + deltaStartMs);
    }

    public long realStart;

    @Override
    public void run() {

        realStart = System.nanoTime();
        println("Real start : " + realStart);
    }
    private static void println(String msg) {
        System.out.println(msg);
    }

}

在我的系统上显示:

After start: 40062314666459
Real start : 40062314706827 
Delta start: 40368 
Delta start ms.: 0

这意味着失去了一点时间。我确信,如果你衡量执行System.out.println(timer)需要多长时间,你会看到更多的时间丢失。所有这些小部分最终加起来相当一段时间没有考虑到。
最后一点:System.nanoTime()System.currentTimeMillis()也需要时间来执行(测量时间需要时间)。