简体   繁体   English

java synchronized方法不工作?

[英]java synchronized on method Not working?

I'm experimenting Java Multi-Threading using synchronization on method comparing with Atomic variables (java.util.concurrent.atomic package). 我正在尝试使用方法上的同步与原子变量(java.util.concurrent.atomic包)进行Java多线程。

Below are the classes: 以下是课程:

// Interface ICounter.java
        public interface ICounter {
            public void increment();
            public void decrement();
            public int value();
        }

// Class Counter.java
    public class Counter implements ICounter {
        private int c = 0;

        @Override
        public void increment() {
            c++;
        }

        @Override
        public void decrement() {
            c--;
        }

        @Override
        public int value() {
            return c;
        }
    }

// Class AtomicCounter.java
    import java.util.concurrent.atomic.AtomicInteger;

    public class AtomicCounter implements ICounter {
        private AtomicInteger c = new AtomicInteger(0);

        @Override
        public void increment() {
            c.incrementAndGet();
        }

        @Override
        public void decrement() {
            c.decrementAndGet();
        }

        @Override
        public int value() {
            return c.get();
        }

        public long getIncrement() {
            return c.incrementAndGet();
        }
    }

// Class MainProg.java
    public class MainProg {
        public static void main(String args[]) {
            ICounter counter = new AtomicCounter();
                    //ICounter counter = new SynchronizedCounter();
            Thread thread1 = new Thread(new CountRunner(counter));
            Thread thread2 = new Thread(new CountRunner(counter));

            thread1.start();
            thread2.start();
        }
    }

    class CountRunner implements Runnable {
        private ICounter counter;
        public CountRunner(ICounter counter) {
            this.counter = counter;
        }

        public void run() {
            while (true) {
                counter.increment();
                System.out.println(Thread.currentThread().getName() + " count=" + counter.value());
                System.out.println("-------------------");
                try {
                    Thread.sleep(2000L);
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }

The results from running either the Atomic or Synchronized do not show that the variable integer is thread-safe, eg: 运行Atomic或Synchronized的结果不显示变量integer是线程安全的,例如:

Thread-0 count=1
-------------------
Thread-1 count=2
-------------------
Thread-0 count=3
-------------------
Thread-1 count=4
-------------------
Thread-0 count=5
-------------------
Thread-1 count=6
-------------------
Thread-0 count=7
-------------------
Thread-1 count=8
-------------------
Thread-0 count=10
-------------------
Thread-1 count=10
-------------------

From the results, the last 2 lines show the 2 threads were accessing the same value of integer variable of the counter class. 从结果中,最后两行显示2个线程正在访问计数器类的整数变量的相同值。 Perhaps I am missing something here? 也许我在这里错过了一些东西?

Thanks! 谢谢!

because your counter.increment() and System.out.println is not one atomic action. 因为你的counter.increment()System.out.println不是一个原子动作。

Thread 1               Thread2

increment

                       increment

                       System.out.println  // print 10

System.out.println  
// print 10 too

You're incrementing the value in one step, then getting the value in another step. 您只需一步递增值,然后在另一步中获取值。 While each of these individual steps is guaranteed to be atomic by the underling AtomicInteger class, the fact that you make two separate operations leaves the value you see in your print statement at the mercy of the order of execution of the threads. 虽然这些单独的步骤中的每一个都被AtomicInteger类保证为原子,但是您进行两个单独的操作这一事实会使您在print语句中看到的值受到线程执行顺序的影响。

To be able to accurately display the value updated by a given thread, you need to both update and get the resulting value in a single operation, which your getIncrement() method does. 为了能够准确显示给定线程更新的值,您需要在getIncrement()方法执行的单个操作中更新并获取结果值。 The code which would give you the expected results would look like this: 能给你预期结果的代码如下所示:

int changedValue = counter.getIncrement();
System.out.println(Thread.currentThread().getName() + " count=" + changedValue);

What you missed is that your AtomicCounter class does work correctly, and the observed behaviour occurs becase the threads switched between the call to .increment() and .value() : 您错过的是您的AtomicCounter类确实正常工作,并且由于线程在.increment().value()的调用之间切换而发生观察到的行为:

-------------------
Thread-0 increment -> value = 9
-------------------
Thread-1 increment -> value = 10
-------------------
Thread-0 print value <- 10
-------------------
Thread-1 print value <- 10
-------------------

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM