对于普通方法:锁是当前实例对象。 对于静态方法:锁是当前类的Class对象。也叫类锁。 对于方法块:锁是Synchronized括号里配置的对象。也叫对象锁。
当我们不加锁的时候,两个线程互不影响,说不定谁先执行 Person类:
public class Person {
public void m1(String s){
System.out.println(s + "开始执行m1");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( s + "执行完m1");
}
public void m2(String s){
System.out.println(s + "开始执行m2");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( s + "执行完m2");
}
public static void m3(String s){
System.out.println(s + "开始执行m3");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( s + "执行完m3");
}
public static void m4(String s){
System.out.println(s + "开始执行m4");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( s + "执行完m4");
}
}
Test类:
public class Test {
public static void main(String[] args) {
Person p = new Person();
Thread t1 = new Thread(){
@Override
public void run(){
p.m1("线程1");
}
};
Thread t2 = new Thread(){
@Override
public void run(){
Person.m3("线程2");
}
};
t1.start();
t2.start();
}
}
运行结果:
1.当给普通方法加上锁: 给普通方法加上锁相当于给这个对象上了锁,锁住的是对象
Person类:
public class Person {
public synchronized void m1(String s){
System.out.println(s + "开始执行m1");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( s + "执行完m1");
}
public synchronized void m2(String s){
System.out.println(s + "开始执行m2");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( s + "执行完m2");
}
}
Test类:
public class Test {
public static void main(String[] args) {
Person p = new Person();
Thread t1 = new Thread(){
@Override
public void run(){
p.m1("线程1");
}
};
Thread t2 = new Thread(){
@Override
public void run(){
p.m2("线程2");
}
};
t1.start();
t2.start();
}
}
运行结果: 当线程1执行m1的时候,线程2是不能执行m2的,只有等线程1执行完m1,m1方法出栈后线程2才可以执行m2. 但是并不妨碍其他对象的执行。如果new出p1的话,p1调用m2是不影响的。不同对象之间是互不干扰的。 同样,加锁的也不影响不加锁的,也就是说,如果m2是没加锁的话,是不影响线程2执行的。
2.当给静态方法加上锁,锁住的是这个类 Person类:
public class Person {
public synchronized static void m3(String s){
System.out.println(s + "开始执行m3");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( s + "执行完m3");
}
public synchronized static void m4(String s){
System.out.println(s + "开始执行m4");
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println( s + "执行完m4");
}
}
Test类:
public class Test {
public static void main(String[] args) {
Thread t1 = new Thread(){
@Override
public void run(){
Person.m3("线程1");
}
};
Thread t2 = new Thread(){
@Override
public void run(){
Person.m4("线程2");
}
};
t1.start();
t2.start();
}
}
锁住静态方法相当于锁住了整个类,其他带锁的静态方法都不可以访问,如果这个类里的某个方法不带锁,那没事,互不干扰。也就是说,带锁的只能让你不能访问其他带锁的,如果不带锁不受此影响。如果有N个加锁的静态方法,在多线程情况下,如果其中一个线程访问了其中的一个静态的带锁方法,那么这个类的其他的静态加锁的方法不能被访问,需要等到那个被调用的被调用完,才能被调用。
同样,对象锁和类锁互不影响。
未完待续。。。
|