Java:为什么我的同步输出仍然如此随机

标签 java synchronization

所以我第一次练习同步。我正在尝试实现 Oracle Java 并发教程中一般描述的实践概念。

这个想法是有一个特殊的 Counter 对象,具有递增、递减和显示值的方法。我的目标是让它由两个不同的线程运行以生成随机冲突,然后通过同步解决这些冲突。到目前为止,我觉得第二部分不起作用,我不知道我做错了什么。

我在下面粘贴的代码很简单。有两个线程,有两个可运行对象。每个可运行的:

1) 包含对同一单个 Counter 对象的引用 2)循环运行五次 3)每次循环运行时 hibernate 1秒 4) 打印Counter的当前值。

MyRunnable1 和 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();
            }
        }
    }


}

最佳答案

同步并不意味着排序。也许“同步”这个词有误导性。在您的情况下,当一个线程具有同步方法时,这意味着在给定的瞬间最多有一个线程可以在相关对象上运行同步方法。

您可以将“同步”理解为“一次一个”。

每当有多个线程运行时,每个线程的进度由系统决定。此外,Thread.sleep 保证在给定的时间间隔内至少 hibernate ,但准确。这两个事实结合起来将为您提供随机排序。

关于Java:为什么我的同步输出仍然如此随机,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30282748/

相关文章:

Java JFrame/JButton/Box - 没有按钮出现

c++ - 一个结构中的条件变量、互斥锁和标志

python - Git:保持同一文件的两个位置同步

sql - 我想将本地数据库与在线数据库同步

java - org.apache.spark.sql.AnalysisException : Can't extract value from UDF_DTTM_3#54: need struct type but got timestamp;

java - java.util.Dates 的数值稳定平均值

java - 使用instanceof运算符进行反序列化

java - 如何绕过 Class.forName() 方法

Java同步性能

ios - 保持两个 AVPlayer 同步