在java中同步线程

时间:2011-03-10 18:54:06

标签: java multithreading

美好的一天! 我遇到了在java中同步线程的问题。我正在开发创建计时器的程序,并允许重置,删除和停止。只是为了学习如何使用线程。

问题是代码只给了一段时间同步......我无法理解我的错误。也许我的方式是错的,所以我想知道如何解决这个问题。

我有下一个代码:

public class StopWatch
{
    //Create and start our timer
    public synchronized void startClock( final int id )
    {                                 
            //Creating new thread.
            thisThread = new Thread()
            {
                @Override
                 public void run()
                 {
                    try
                    {                                               
                        while( true )
                        {
                            System.out.printf( "Thread [%d] = %d\n", id, timerTime );
                            timerTime  += DELAY;                                        //Count 100 ms
                            Thread.sleep( DELAY );                                      
                        }
                    }
                    catch( InterruptedException ex )
                    {
                        ex.printStackTrace();
                    }
                 }
            };

            thisThread.start();           
    }

…
   //Starting value of timer
   private long timerTime = 0;
   //Number of ms to add and sleep                                      
   private static final int DELAY    = 100;                                  

    private Thread thisThread;
} 

我将此类称为:

StopWatch s = new StopWatch(1);
          s.startClock();
StopWatch s2 = new StopWatch(2);
          s2.startClock();

5 个答案:

答案 0 :(得分:6)

我想你可能误解了“同步”。

这并不意味着线程在完全同步的时间内运行 - 而是一次只允许一个线程执行同步代码块。在你的情况下,“synchronized”没有区别,因为你是从同一个线程调用startClock方法....

通常,Java(实际上是大多数高级语言)都不可能保证两个线程在完全相同的时钟时间执行操作,即使您有多个内核,因为它们总是容易被操作系统延迟调度程序或JVM垃圾收集暂停等。

另外,Thread.sleep(...)作为计时机制是不可靠的,因为它睡眠的数量只是近似值。你受线程调度程序的支配。

建议的解决方案:

如果你想要一个与线程无关的计时机制,请使用System.currentTimeMillis()

答案 1 :(得分:2)

你是什么意思"只能让你同步一段时间?"你在这里同步的唯一一件事是startClock方法,这意味着两个线程不会同时在该方法中(并且它看起来不像你正在做的那样)。例如,如果要同步对timerTime的访问,则需要在递增timerTime周围的thread run方法中放置一个synchronized块(或者你可以使用AtomicLong)。

答案 2 :(得分:0)

您可能应该重新阅读“synchronize”关键字的文档。我非常确定在这种情况下它所做的就是保持两个StartClock()调用同时执行,这不会发生,因为它们是从一个线程一个接一个地调用的。一旦计时器线程开始,如果这是你的目标,就没有什么能保持它们的同步。

答案 3 :(得分:0)

您的第一个问题是这是一个仅限时间的解决方案。这很糟糕,因为程序无法控制执行所需的时间。某些操作比其他操作花费更多时间,并且进程中的每个线程不会同时执行。一般来说,这不会同步任何东西,除非你能保证其他一切都是一样的。 。

了解http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Semaphore.html,您也可以

的Thread.join();使主循环等待子线程的执行在继续执行之前完成。

答案 4 :(得分:0)

我认为你误解了同步意味着什么。同步是为了确保多个线程对某个代码块的访问权限受到限制,这样就不会在两个线程之间产生冲突。

我认为您可能更感兴趣的是CyclicBarrier或CountDownLatch。两者都可以用来“同步”(在这种情况下是重载使用)多个线程,这样他们就可以尝试同时开始做事。

但是,请注意,多个线程无法在完全同一时刻执行操作。你几乎可以尝试在同一时间鼓励他们这样做。其余部分受制于系统核心的OS调度。如果你有一个核心,它们将永远不会同时运行。