java中的同步线程
再会! 我遇到了有关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();
Good day!
I got the problem about synchronizing threads in java. I am developing program which creates timers and allows to reset it, delete and stop. Just to learn how to using threads.
The problem is that code gives synchronizing only for some time... I can't understand my mistake. Maybe my way is wrong so i would like to know how to solve this issue.
I have next code:
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;
}
I call this Class like:
StopWatch s = new StopWatch(1);
s.startClock();
StopWatch s2 = new StopWatch(2);
s2.startClock();
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
我想你可能误解了“同步”。
这并不意味着线程在完全同步的时间内运行 - 而是一次只允许一个线程执行同步代码块。在你的情况下,“同步”没有什么区别,因为你是从同一个线程调用 startClock 方法......
一般来说,在 Java (实际上是大多数高级语言)中不可能保证两个线程精确地执行操作相同的时钟时间,即使你有多个核心,因为它们总是容易被操作系统调度程序或 JVM 垃圾收集暂停等延迟。
此外,Thread.sleep(...) 作为计时机制并不可靠,因为它的数量它的睡眠时间只是近似值。你受线程调度程序的支配。
建议的解决方案:
使用 系统.currentTimeMillis() 如果你想要一个独立于线程的计时机制。
I think you may have misunderstood "synchronized".
It does not mean that the threads run in exactly synchronized time - rather that only one thread at a time is allowed to be executing the synchronized code block. In your case "synchronized" makes no difference, since you are calling the startClock method from the same thread....
In general, it is impossible in Java (and indeed most high level languages) to guarantee that two threads perform actions at exactly the same clock time even if you have multiple cores, since they are always vulnerable to being delayed by the OS scheduler or JVM garbage collection pauses etc.
Also, Thread.sleep(...) is unreliable as a timing mechanism, as the amount it sleeps for is only approximate. You're at the mercy of the thread scheduler.
Suggested solution:
use System.currentTimeMillis() if you want a thread-independent timing mechansim.
“只让你同步一段时间”是什么意思?这里唯一同步的是 startClock 方法,这意味着两个线程不会同时位于该方法中(而且看起来您并没有这样做)。例如,如果您想同步对timerTime的访问,则需要在递增的timerTime周围的线程运行方法中放置一个同步块(或者您可以使用AtomicLong)。
What do you mean it "only gives you synchronizing for some time?" The only thing you have synchronized here is the startClock method, which just means that two threads will not be within that method at the same time (and it doesn't look like you are doing that anyway). If you wanted to synchronize access to timerTime for example, you would need to put a synchronized block inside thread run method around the incrementing timerTime (or you could use an AtomicLong).
您可能应该重新阅读“synchronize”关键字的文档。我非常确定在这种情况下,它要做的就是阻止 StartClock() 的两个调用同时执行,鉴于此代码,这种情况不会发生,因为它们是从一个线程一个接一个地调用的。一旦计时器线程开始,就没有什么可以使它们保持同步(如果这是您的目标)。
You should probably re-read the documentation for the "synchronize" keyword. I'm pretty sure in this case all it would do is keep the two calls of StartClock() from executing at the same time, which wouldn't happen given this code because they're called one after the other from one thread. Once the timer thread begins, there's nothing keeping them synchronized, if that's your goal.
您的第一个问题是,这是一个仅基于时间的解决方案。这很糟糕,因为程序无法控制执行时间。某些操作比其他操作花费更多时间,并且进程中的每个线程不会同时执行。一般来说,除非您能保证其他所有内容都相同,否则这不会同步任何内容。 。 。
了解http://download.oracle.com /javase/6/docs/api/java/util/concurrent/Semaphore.html 你也可以做
Thread.join();使主循环等待子线程执行完成后再继续执行。
Your first problem is that this is a time based only solution. This is bad because the program has no control over how long it takes to execute. Some operations take more time than others and each thread within your process doesn't execute at the same time. In general this won't synchronize anything unless you can guarantee everything else is the same . . .
Read about http://download.oracle.com/javase/6/docs/api/java/util/concurrent/Semaphore.html and you can also do
Thread.join(); to make the main loop wait for the execution of the child thread to finish before continuing execution.
我认为您误解了同步的含义。同步是为了确保多个线程对某个代码块的访问受到限制,这样两个线程之间就不会发生冲突。
我认为您可能更感兴趣的是 CyclicBarrier 或 CountDownLatch。两者都可用于“同步”(在本例中为重载使用)多个线程,以便它们尝试同时开始执行操作。
但是,请注意,不可能让多个线程在完全相同同一时刻执行操作。你只能尝试鼓励他们在大约同一时间做这些事情。其余的则取决于系统内核上的操作系统调度。如果你有一个核心,它们永远不会同时运行。
I think you misunderstood what synchronized means. Synchronized is to ensure that multiple threads have limited access to a certain block of code so that you don't get conflicts between the two threads.
I think what you may be more interested in is a CyclicBarrier or a CountDownLatch. Both can be used to "synchronize" (overloaded use in this case) multiple threads so that they try to start doing things at the same time.
However, be aware that it's impossible to have multiple threads do things at exactly the same instant. You can only try to encourage to do them at about the same time. The rest is subject to OS scheduling on the cores in the system. And if you have a single core, they will never run at the same time.