英文:
Not getting desired result when using synchronized keyword in Java multithreading
问题
以下是您提供的内容的翻译部分:
我有两个文件,App.java 和 Runner.java
App.java -->
public class App {
private static Thread thread1 = new Runner(1);
private static Thread thread2 = new Runner(2);
public static void main(String[] args) throws InterruptedException {
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.printf("Count = %d\n", Runner.getCount());
}
}
Runner.java -->
public class Runner extends Thread {
private volatile static int count = 0;
private int option = 0;
private synchronized void increment() {
count++;
}
private synchronized void decrement() {
count--;
}
public Runner(int option) {
this.option = option;
}
public static int getCount() {
return count;
}
@Override
public void run() {
switch (option) {
case 1:
for (int i = 1; i <= 10000; i++) {
increment();
}
break;
case 2:
for (int i = 1; i <= 10000; i++) {
decrement();
}
break;
}
}
}
在这里,我试图从 main 线程创建两个 threads,并从这两个线程中访问一个共同的变量,这两个线程将同时操作这个共同的变量。
我试图创建一个演示用的实现 synchronized 关键字的示例。
在我的示例中,在 Runner.java 中 -
我将 Runner 类通过 extends 关键字作为 Thread 类的子类,同时在其主体中覆盖了 run() 方法。
接下来,我使用一个构造函数来获取一个 option,并在 run() 方法中运行相应的代码,使用 switch - case 语句块。共同的变量是 count,它是一个初始值为 0 的静态变量。
有两个方法,都使用了 synchronized 关键字 - increment() 和 decrement(),分别将 count 的值增加和减少 1。
对于 option 1,run() 方法使用一个循环来运行 increment() 10,000 次。
对于 option 2,run() 方法使用一个循环来运行 decrement() 10,000 次。
因此,count 的最终值应该为 0。
在 App.java 中 -
我创建了两个线程 - thread1 和 thread2,它们都是 Runner class 的实例,并分别传递了构造函数参数 1 和 2。
我使用 thread.start() 运行这两个线程,并使用 thread.join() 等待这两个线程的完成。
现在,我打印了 count 的值。预期值应该是 0。但实际上不是。在每次执行中,它都接近于 0,但不是 0。
因此,我在哪里出错了,如何纠正我的代码?
英文:
I have two files, App.java and Runner.java
App.java -->
public class App {
private static Thread thread1 = new Runner(1);
private static Thread thread2 = new Runner(2);
public static void main(String[] args) throws InterruptedException {
thread1.start();
thread2.start();
thread1.join();
thread2.join();
System.out.printf("Count = %d\n", Runner.getCount());
}
}
Runner.java -->
public class Runner extends Thread {
private volatile static int count = 0;
private int option = 0;
private synchronized void increment() {
count++;
}
private synchronized void decrement() {
count--;
}
public Runner(int option) {
this.option = option;
}
public static int getCount() {
return count;
}
@Override
public void run() {
switch (option) {
case 1:
for (int i = 1; i <= 10000; i++) {
increment();
}
break;
case 2:
for (int i = 1; i <= 10000; i++) {
decrement();
}
break;
}
}
}
Here I am trying to create two threads from main thread and access a common variable from both the threads where both the threads will manipulate this common variable at the same time.
I am trying to create a demo for implementation for the synchronized keyword.
In my example, in Runner.java -
I am making Runner class a child class of Thread using extends keyword and overriding the run() method in body.
Next, I am using a constructor to get an option and running the respective code in run() method in a switch - case block. The common variable is count which is static with initial value 0.
There are two methods, both use the synchronized keyword - increment() and decrement() which increase and decrease the value of count by 1 respectively.
For option 1 run() method uses a for loop to run increment() 10,000 times.
For option 2 run() method uses a for loop to run decrement() 10,000 times.
As such the end value of count should be 0.
In App.java -
I am creating two threads - thread1, thread2 which are instances of Runner class and passing constructor argument 1 and 2 respectively.
I am running the two threads using thread.start() and waiting for completion of the two threads using thread.join()
Now, I am printing the value of count. The value is expected to be 0. But it is not. In each execution it is near to 0 but not 0.
So, where am I going wrong and how to correct my code?
答案1
得分: 1
count 是静态的,意味着只有一个这样的变量。
increment 和 decrement 都不是静态的,这意味着它们在 this 上是同步的 - 即两个独立的 Runner 实例。
将这些方法改为静态的:
private static void increment() {
synchronized (Runner.class) {
count++;
}
}
private static void decrement() {
synchronized (Runner.class) {
count--;
}
}
或者使用显式的互斥对象:
private static int count = 0;
private static Object mutex = new Object();
private int option = 0;
private void increment() {
synchronized (mutex) {
count++;
}
}
private void decrement() {
synchronized (mutex) {
count--;
}
}
英文:
count is static meaning there is only one such variable.
Both increment and decrement are not static which means they are synchronized on this - that is two separate Runner instances.
Make those method static:
private synchronized static void increment() {
count++;
}
private synchronized static void decrement() {
count--;
}
or use explicit mutex object:
private static int count = 0;
private static Object mutex = new Object;
private int option = 0;
private void increment() {
synchronized (mutex) {
count++;
}
}
private void decrement() {
synchronized (mutex) {
count--;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。


评论