java基础–synchronized
大家都知道,synchronized关键字在java编程中的作用是进行线程同步的,它可以保证一段代码在多线程开发中不被同时执行。
synchronized的锁可以分为类锁和对象锁。
类锁:synchronized作用于static方法或者锁Object.class都会对该类加锁,也就是上面说的类锁。
对象锁:当synchronized作用于一个普通方法或者作用于具体的类对象时会对该对象加锁,也就是上面说的对象锁。
很多人会认为给一个static变量加锁时,是给该static变量所在类加了类锁,其实不是,它只是给static变量,也可以说是static对象或者引用加了锁。唯一的特点是static变量属于一个类,多个该类的对象调用有锁的static变量时都会等待而已,本质还是对象锁。
举个苹果
类A 和类B
定义一个static变量,使用的时候给它加锁(对象锁)
public class A implements Runnable{
public static String a = "123";
@Override
public void run() {
synchronized (a) {
try {
for(int n =0;n<10;n++) {
Thread.sleep(1000);
System.out.println(n+"A"+a);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class B implements Runnable{
@Override
public void run() {
synchronized (A.a) {
try {
for(int n =0;n<10;n++) {
Thread.sleep(1000);
System.out.println(n+"B"+A.a);
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) throws InterruptedException {
new Thread(new A()).start();
Thread.sleep(2000);
new Thread(new B()).start();
}
}
结果
0A123
1A123
2A123
3A123
4A123
5A123
6A123
7A123
8A123
9A123
0B123
1B123
2B123
3B123
4B123
5B123
6B123
7B123
8B123
9B123
根据结果可以看出来,锁生效了,两个对象都对static变量加锁了,最后同步执行。
synchronized关键字,需要注意的是,我们通常说的是某某方法或者代码块获取了某个对象或者某个类的锁,说明你要执行加锁的代码时,必须先获取对应的锁,而在执行没有加锁的代码时,不需要获取锁。
很多人会认为当执行一段有锁的代码时,不能执行该类或者对象的其他方法,直到释放锁,这是错误的。只有执行一段有锁的代码时才需要获取对应的锁,其他情况正常执行。
另外,类锁和对象锁是互不干扰的,可以混合使用。