java 中的同步方法问题
synchronized method issue in java
下面显示了三种不同的同步方法。
甲:
public synchronized static int addCount1() {
for (int i = 0; i < 10000; i++) {
count++;
}
return count;
}
乙:
static void addCount2() {
synchronized (TestDoubleThread.class) {
for (int i = 0; i < 10000; i++) {
count++;
}
}
}
C:
void addCount3(String key) {
synchronized (myMap.get(key)) {
for (int i = 0; i < 10000; i++) {
count++;
}
}
}
他们都可以按照我的预期进行同步。但是,我想知道哪个更好,以及它们之间的显着差异是什么。特别是对于案例 B 和案例 C。
这是我的完整代码:
public class TestDoubleThread extends Thread {
String jobNmae;
static int count = 0;
TestDoubleThread(String jobName) {
this.jobNmae = jobName;
}
public static void main(String[] args) throws Exception {
TestDoubleThread t1 = new TestDoubleThread("A");
TestDoubleThread t2 = new TestDoubleThread("B");
t1.start();
t2.start();
Thread.sleep(3 * 1000L);
System.out.println("count=" + TestDoubleThread.count);
}
public void run() {
// addCount2();
addCount3("A");
}
public synchronized static int addCount1() {
for (int i = 0; i < 10000; i++) {
count++;
}
return count;
}
static void addCount2() {
synchronized (TestDoubleThread.class) {
for (int i = 0; i < 10000; i++) {
count++;
}
}
}
void addCount3(String key) {
synchronized (myMap.get(key)) {
for (int i = 0; i < 10000; i++) {
count++;
}
}
}
public static java.util.Map<String, TestDoubleThread> myMap = new java.util.HashMap<String, TestDoubleThread>();
static {
myMap.put("A", new TestDoubleThread("A"));
myMap.put("B", new TestDoubleThread("B"));
}
}
addCount2
在 TestDoubleThread.class
上同步,而 addCount3
在 myMap.get(key)
返回的 TestDoubleThread
实例上同步。由于您使用 addCount3("A");
执行它,因此两个线程在同一个对象上同步,因此一个必须等待另一个才能执行该方法。因此它的行为与 addCount2
完全相同,后者也在同一个对象上同步。
另一方面,如果将其更改为 addCount3(this.jobNmae)
,每个线程将在不同的对象上同步,因此两个线程将能够同时执行 addCount3
,你的 count
会被搞砸的。
下面显示了三种不同的同步方法。
甲:
public synchronized static int addCount1() {
for (int i = 0; i < 10000; i++) {
count++;
}
return count;
}
乙:
static void addCount2() {
synchronized (TestDoubleThread.class) {
for (int i = 0; i < 10000; i++) {
count++;
}
}
}
C:
void addCount3(String key) {
synchronized (myMap.get(key)) {
for (int i = 0; i < 10000; i++) {
count++;
}
}
}
他们都可以按照我的预期进行同步。但是,我想知道哪个更好,以及它们之间的显着差异是什么。特别是对于案例 B 和案例 C。
这是我的完整代码:
public class TestDoubleThread extends Thread {
String jobNmae;
static int count = 0;
TestDoubleThread(String jobName) {
this.jobNmae = jobName;
}
public static void main(String[] args) throws Exception {
TestDoubleThread t1 = new TestDoubleThread("A");
TestDoubleThread t2 = new TestDoubleThread("B");
t1.start();
t2.start();
Thread.sleep(3 * 1000L);
System.out.println("count=" + TestDoubleThread.count);
}
public void run() {
// addCount2();
addCount3("A");
}
public synchronized static int addCount1() {
for (int i = 0; i < 10000; i++) {
count++;
}
return count;
}
static void addCount2() {
synchronized (TestDoubleThread.class) {
for (int i = 0; i < 10000; i++) {
count++;
}
}
}
void addCount3(String key) {
synchronized (myMap.get(key)) {
for (int i = 0; i < 10000; i++) {
count++;
}
}
}
public static java.util.Map<String, TestDoubleThread> myMap = new java.util.HashMap<String, TestDoubleThread>();
static {
myMap.put("A", new TestDoubleThread("A"));
myMap.put("B", new TestDoubleThread("B"));
}
}
addCount2
在 TestDoubleThread.class
上同步,而 addCount3
在 myMap.get(key)
返回的 TestDoubleThread
实例上同步。由于您使用 addCount3("A");
执行它,因此两个线程在同一个对象上同步,因此一个必须等待另一个才能执行该方法。因此它的行为与 addCount2
完全相同,后者也在同一个对象上同步。
另一方面,如果将其更改为 addCount3(this.jobNmae)
,每个线程将在不同的对象上同步,因此两个线程将能够同时执行 addCount3
,你的 count
会被搞砸的。