代码如下:
package testOther;import java.util.HashMap;public class TestMig { /**
* @param args
*/
public static void main(String[] args) {
new TestMig();
} public static HashMap<String, String> map = new HashMap<String, String>(); public TestMig() {
myThreadClass1 thread1 = new myThreadClass1();
myThreadClass2 thread2 = new myThreadClass2();
Thread t1 = new Thread(thread1);
Thread t2 = new Thread(thread2);
t1.start();
t2.start();
} class myThreadClass1 implements Runnable { public void run() { synchronized (map) {
System.out.println("start" + Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + " "
+ map.hashCode());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("end" + Thread.currentThread().getName());
}
}
} class myThreadClass2 implements Runnable {
public void run() {
System.out.println("start" + Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + " "
+ map.hashCode());
map.put("1", "haha");
System.out.println("end" + Thread.currentThread().getName());
}
}}问题:这个问题是根据刚才有个网友的问题变化而来,我的map是个静态变量,就是说两个线程应该是共享同一个map的,为什么线程1对map加锁后仍然不能阻止线程2对map的操作?谢谢!
package testOther;import java.util.HashMap;public class TestMig { /**
* @param args
*/
public static void main(String[] args) {
new TestMig();
} public static HashMap<String, String> map = new HashMap<String, String>(); public TestMig() {
myThreadClass1 thread1 = new myThreadClass1();
myThreadClass2 thread2 = new myThreadClass2();
Thread t1 = new Thread(thread1);
Thread t2 = new Thread(thread2);
t1.start();
t2.start();
} class myThreadClass1 implements Runnable { public void run() { synchronized (map) {
System.out.println("start" + Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + " "
+ map.hashCode());
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("end" + Thread.currentThread().getName());
}
}
} class myThreadClass2 implements Runnable {
public void run() {
System.out.println("start" + Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + " "
+ map.hashCode());
map.put("1", "haha");
System.out.println("end" + Thread.currentThread().getName());
}
}}问题:这个问题是根据刚才有个网友的问题变化而来,我的map是个静态变量,就是说两个线程应该是共享同一个map的,为什么线程1对map加锁后仍然不能阻止线程2对map的操作?谢谢!
startThread-0
Thread-0 0
startThread-1
Thread-1 0
endThread-1
endThread-0你的呢
我把sleep改了,换成会影响时间的代码:
package testOther;import java.io.File;
import java.io.IOException;
import java.util.HashMap;public class TestMig { /**
* @param args
*/
public static void main(String[] args) {
new TestMig();
} public static HashMap<String, String> map = new HashMap<String, String>(); public TestMig() {
myThreadClass1 thread1 = new myThreadClass1();
myThreadClass2 thread2 = new myThreadClass2();
Thread t1 = new Thread(thread1);
Thread t2 = new Thread(thread2);
t1.start();
t2.start();
} class myThreadClass1 implements Runnable { public void run() { synchronized (map) {
System.out.println("start" + Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + " "
+ map.hashCode());
// try {
// Thread.sleep(10000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
for (int i = 0; i < 10; i++) {
File file = new File("d:\\" + i + ".txt");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} System.out.println("end" + Thread.currentThread().getName());
}
}
} class myThreadClass2 implements Runnable {
public void run() {
System.out.println("start" + Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + " "
+ map.hashCode());
map.put("1", "haha");
System.out.println("end" + Thread.currentThread().getName());
}
}}结果:
startThread-0
Thread-0 0
startThread-1
Thread-1 0
endThread-1
endThread-0即在1线程结束之前,就是synchronized块中,2线程仍然访问了map
myThreadClass2 里面map的访问没有同步,可以随便访问的
import java.io.File;
import java.io.IOException;
import java.util.HashMap;public class TestMig { /**
* @param args
*/
public static void main(String[] args) {
new TestMig();
} public static HashMap<String, String> map = new HashMap<String, String>(); public TestMig() {
myThreadClass1 thread1 = new myThreadClass1();
myThreadClass2 thread2 = new myThreadClass2();
Thread t1 = new Thread(thread1);
Thread t2 = new Thread(thread2);
t1.start();
t2.start();
} class myThreadClass1 implements Runnable { public void run() { synchronized (map) {
System.out.println("start" + Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + " "
+ map.hashCode());
// try {
// Thread.sleep(10000);
// } catch (InterruptedException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
for (int i = 0; i < 10; i++) {
File file = new File("d:\\" + i + ".txt");
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
} System.out.println("end" + Thread.currentThread().getName());
}
}
} class myThreadClass2 implements Runnable {
public void run() {
System.out.println("start" + Thread.currentThread().getName());
System.out.println(Thread.currentThread().getName() + " "
+ map.hashCode());
map.put("1", "haha");
System.out.println(map.size());
System.out.println("end" + Thread.currentThread().getName());
}
}}你把map的大小打印出来
我的结果是:
startThread-0
Thread-0 0
endThread-0
startThread-1
Thread-1 0
1
endThread-1
map是在线程0操作完后才被put,至于你的程序结果
startThread-0
Thread-0 0
startThread-1
Thread-1 0 //个人理解,我线程也不熟,打印出map的hashcode不能算访问了map吧
endThread-1
endThread-0
map是静态共享对象,myThreadClass2 和myThreadClass1 引用的是同一个map
打印出map的hashCode是访问了map的hashcode方法,怎么能不算访问map -_-!
对一个变量加锁,所有该变量的操作都是原子性的。另外,endThread-0 是在2线程操作完了map以后才打出来的
synchronized (map) 我想LZ这里只是在这个类里同步了,但class myThreadClass1 无关。
你的意思是synchronized不是对map加锁?只是表示得到锁?有点晕,那加锁是什么?
import java.util.*;public class Test { /**
* @param args
*/
public static void main(String[] args) {
new Test();
}
//加锁方法
public static Map map = Collections.synchronizedMap(new HashMap<String, String>()); public Test() {
myThreadClass1 thread1 = new myThreadClass1();
myThreadClass2 thread2 = new myThreadClass2();
Thread t1 = new Thread(thread1);
Thread t2 = new Thread(thread2);
t1.start();
t2.start();
} class myThreadClass1 implements Runnable { public void run() {
System.out.println("start" + Thread.currentThread().getName());
//开始锁定
System.out.println(Thread.currentThread().getName() + " "
+ map.hashCode());
try {
//暂停10秒
Thread.sleep(10000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("end" + Thread.currentThread().getName());
}
} class myThreadClass2 implements Runnable {
public void run() {
System.out.println("start" + Thread.currentThread().getName());
//开始锁定
System.out.println(Thread.currentThread().getName() + " "
+ map.hashCode());
map.put("1", "haha");
System.out.println("end" + Thread.currentThread().getName());
}
}}
2因为线程2对map操作不需要得到map的锁线程加锁并不代表不能访问被加锁对象,而是另外一个对象不能得到这个对象的锁,即有且只有一个线程能够得到这个锁