当在一个方法中用线程同步加锁,任何时刻只能运行一个线程调用这个方法,但是方法中加锁的变量可以在其他普通的 方法中对这个变量进行读写?现贴出一段代码说明:
public class lesson909 implements Runnable {
int b=100,a=10;
public synchronized void m1() throws Exception{
b=1000; //对这个方法采用线程同步
Thread.sleep(3000);
System.out.println("b="+b);
}
public void m2(){
b=2000;
System.out.println("m2:b="+b);
}
public void run() {
try {
m1();
}catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String [] args) {
lesson909 t1 =new lesson909();
Thread t= new Thread(t1);
t1.m2();
t.start(); //线程开始,执行run方法,run方法中调用m1方法,b=1000,然后睡眠
try {
Thread.sleep(100); //确保线程已经开始执行
}catch(InterruptedException e) {
}
t1.m2(); //调用方法m2,在m2中b=2000,发现虽然线程中对b进行了加锁,但b依旧能在其他地方改变。
//方法m2中将b=2000,然后m1中睡眠的结束,打印b=2000,m2中改变了b,说明已经影响了m1中的b。
System.out.println("main:"+t1.b);
}
}
执行结果如下:
现在在方法m1和m2中都对变量b进行加锁,线程在执行的时候必须等持锁的线程释放锁后,另一个试图获得锁的线程
才能继续执行。
public class lesson909 implements Runnable {
int b=100,a=10;
public synchronized void m1() throws Exception{
b=1000;
Thread.sleep(3000);
System.out.println("b="+b);
}
public synchronized void m2(){ //对方法二也进行了线程同步!!!!!!!!!!!!!!!
b=2000;
System.out.println("m2:b="+b);
}
public void run() {
try {
m1();
}catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String [] args) {
lesson909 t1 =new lesson909();
Thread t= new Thread(t1);
t1.m2();
t.start();
try {
Thread.sleep(100);
}catch(InterruptedException e) {
}
t1.m2();
System.out.println("main:"+t1.b);
}
}
执行结果如下:
总结:
如果在多个方法中对某一变量进行赋值,则在这些方法中都进行线程同步。若只在某个方法中对变量加锁则必须考虑清楚后果。