英文:
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--;
}
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论