java 同步方法不工作?

发布于 2024-09-14 03:04:30 字数 2834 浏览 4 评论 0原文

我正在试验 Java 多线程,使用同步方法与原子变量(java.util.concurrent.atomic 包)进行比较。

下面是这些类:

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

运行 Atomic 或 Synchronized 的结果并不表明变量整数是线程安全的,例如:

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
-------------------

从结果中,最后 2 行显示 2 个线程正在访问整数变量的相同值柜台类。 也许我在这里遗漏了一些东西?

谢谢!

I'm experimenting Java Multi-Threading using synchronization on method comparing with Atomic variables (java.util.concurrent.atomic package).

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, e.g.:

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.
Perhaps I am missing something here?

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

忆依然 2024-09-21 03:04:30

您在一个步骤中递增该值,然后在另一步骤中获取该值。虽然下面的 AtomicInteger 类保证每个步骤都是原子的,但进行两个单独的操作的事实使得您在 print 语句中看到的值受到执行顺序的影响线程。

为了能够准确显示给定线程更新的值,您需要在单个操作中更新并获取结果值,您的 getIncrement() 方法就是这样做的。将为您提供预期结果的代码如下所示:

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

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.

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. 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);
才能让你更想念 2024-09-21 03:04:30

因为您的 counter.increment() 和 System.out.println 不是一个原子操作。

Thread 1               Thread2

increment

                       increment

                       System.out.println  // print 10

System.out.println  
// print 10 too

because your counter.increment() and System.out.println is not one atomic action.

Thread 1               Thread2

increment

                       increment

                       System.out.println  // print 10

System.out.println  
// print 10 too
救星 2024-09-21 03:04:30

您错过的是您的 AtomicCounter 类确实正常工作,并且观察到的行为发生是因为线程在 .increment().value( 的调用之间切换)

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

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():

-------------------
Thread-0 increment -> value = 9
-------------------
Thread-1 increment -> value = 10
-------------------
Thread-0 print value <- 10
-------------------
Thread-1 print value <- 10
-------------------
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文