所以我第一次练习同步。我正在尝试实现一般在Oracle Java Concurrency教程中描述的实践概念。
我们的想法是拥有一个特殊的Counter对象,其中包含递增,递减和显示值的方法。我的目标是让它由两个不同的线程运行以生成随机冲突,然后通过同步解决这些冲突。到目前为止,我觉得第二部分不起作用,我无法弄清楚我做错了什么。
我在下面粘贴的代码很简单。有两个线程,有两个runnables。每个runnable:
1)包含对同一个Counter对象的引用 2)运行循环五次 3)每次循环运行时休眠1秒钟 4)打印计数器的当前值。
MyRunnable1& amp; MyRunnable2是第一个递增计数器,第二个递减计数器。
显然,当我在没有同步方法的情况下运行它时会产生随机结果。但即使在我同步这些方法后,结果仍显然是随机的。
样本结果1: 1 0 1 0 1 0 -1 0 1 0
样本结果2: -1 0 1 0 1 0 1 0 -1 0
我认为应该是什么:它应该始终如一地进入1 0 1 0 1 0等等,直到完成所有循环。如果我错在那里,如果这是我考虑线程行为的方式,请指出。
以下是我的代码。所有想法/建议表示赞赏。这是我第一次尝试以任何方式使用同步,我想让它失效,因为它是一个非常重要的概念。
public class CounterSync {
public static void main(String[] args){
Counter c = new Counter();
Thread t1 = new Thread(new MyRunnable1(c));
Thread t2 = new Thread(new MyRunnable2(c));
t1.start();
t2.start();
System.out.println("Done");
}
public static class Counter{
private int c = 0;
public synchronized void increment(){
c++;
}
public synchronized void decrement(){
c--;
}
public synchronized int value(){
return c;
}
}
public static class MyRunnable1 implements Runnable{
private Counter c;
public MyRunnable1(Counter c){
this.c = c;
}
@Override
public void run(){
try{
for(int i = 0; i < 5; i++){
Thread.sleep(1000);
c.increment();
System.out.println(c.value());
}
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
public static class MyRunnable2 implements Runnable{
private Counter c;
public MyRunnable2(Counter c){
this.c = c;
}
@Override
public void run(){
try{
for(int i = 0; i < 5; i++){
Thread.sleep(1000);
c.decrement();
System.out.println(c.value());
}
}catch(InterruptedException ex){
ex.printStackTrace();
}
}
}
}
答案 0 :(得分:1)
同步并不意味着订购。也许“同步”这个词有误导性。在您的情况下,当一个人有同步方法时,这意味着在给定的时刻,一个线程可以在相关对象上运行 synchronized 方法。
您可以将“同步”视为“一次一个”。
每当运行多个线程时,每个线程将进行多少进程由系统决定。此外,Thread.sleep
保证在给定的时间间隔内至少,但不精确。两个事实相结合将给你随机排序。