简体   繁体   English

Java多线程使用synchronized不是线程安全的

[英]Java multithreading not thread-safe using synchronized

A simple multithreading test with synchronization. 具有同步的简单多线程测试。 I thought if it was "synchronized," other threads would wait. 我想如果它是“同步的”,其他线程会等待。 What am I missing? 我错过了什么?

public class MultithreadingCounter implements Runnable {

    static int count = 0;

    public static void main(String[] args) {
        int numThreads = 4;
        Thread[] threads = new Thread[numThreads];

        for (int i = 0; i < numThreads; i++)
            threads[i] = new Thread(new MultithreadingCounter(), i + "");

        for (int i = 0; i < numThreads; i++)
            threads[i].start();

        for (int i = 0; i < numThreads; i++)
            try {
                threads[i].join();
            } catch (Exception e) {
                e.printStackTrace();
            }
    }           

    @Override
    public void run() {
        increment();
    }

    public synchronized void increment(){
            System.out.print(Thread.currentThread().getName() + ": " + count + "\t");
            count++; // if I put this first or increment it directly in the print line, it works fine.
    }
}

I thought this would display something like: 我认为这会显示如下:

0: 1    2: 0    1: 2    3: 3    

But its actual output: 但它的实际输出:

0: 0    2: 0    1: 0    3: 3    

and other variations like this. 和其他类似的变化。 It should display each increment (ie 0,1,2,3) not in order... 它应该显示每个增量(即0,1,2,3)不按顺序...

Your synchronized keyword is on an instance method. 您的synchronized关键字位于实例方法上。 No two threads can execute this method of one of your thread objects at the same time. 没有两个线程可以同时执行一个线程对象的此方法。 But, that is not what your code does. 但是,这不是你的代码所做的。 Each thread executes the method on its own instance. 每个线程在自己的实例上执行该方法。 The synchronization does not do what you seem to intend. 同步不会达到你想要的目的。 If it were a static method, it would. 如果它是static方法,它会。

Your increment method should be static : 您的increment方法应该是static

public static synchronized void increment() {

Right now, each object is synchronized on that individual instance, but since count is a static variable, you should be synchronizing on the Class object itself. 现在,每个对象在该单个实例上同步,但由于count是一个静态变量,因此您应该在Class对象本身上进行同步。

when synchronized keyword is used before a method, it ensures that that method can be executed by only one thread at a time with respect to that object only. 当在方法之前使用synchronized关键字时,它确保该方法一次只能由一个线程执行。 It does not ensure thread safety from other objects. 它不能确保其他对象的线程安全。

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

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