使用synchronized的Java多线程不是线程安全的
一个简单的同步多线程测试。我想如果它是“同步的”,其他线程会等待。我错过了什么使用synchronized的Java多线程不是线程安全的,java,multithreading,runnable,Java,Multithreading,Runnable,一个简单的同步多线程测试。我想如果它是“同步的”,其他线程会等待。我错过了什么 public class MultithreadingCounter implements Runnable { static int count = 0; public static void main(String[] args) { int numThreads = 4; Thread[] threads = new Thread[numThreads];
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.
}
}
但其实际产出:
0: 0 2: 0 1: 0 3: 3
还有其他类似的变化。它应该不按顺序显示每个增量(即0,1,2,3…您的
synchronized
关键字位于实例方法上。没有两个线程可以同时执行其中一个线程对象的此方法。但是,这不是您的代码所做的。每个线程在自己的实例上执行该方法。同步并没有达到您似乎想要的效果。如果它是一个静态
方法,它会。您的增量
方法应该是静态
:
public static synchronized void increment() {
现在,每个对象都在该实例上同步,但由于
count
是一个静态变量,因此您应该在类
对象本身上同步。当在方法之前使用synchronized关键字时,它确保该方法一次只能由一个线程针对该对象执行。它不能确保其他对象的线程安全 是我让你得到3000次重复,耶:是的,我应该让它静态
(与同步
)充分地选通它,还是他应该让变量波动
(正确)同步就够了。它已经确保了增量与后续读取之间存在“发生在之前”的关系,这是volatile
将添加的全部内容。
public static synchronized void increment() {