并发——synchronized(加锁)
一、声明一个对象,专门用来管理锁
/**
* synchronized关键字
* 对某个对象加锁
*/
public class T {
private int count = 10;
private Object o = new Object();//声明一个对象,专门用来管理锁
public void m() {
synchronized(o) { //任何线程要执行下面的代码,必须先拿到o的锁
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
}
}
二、对this加锁
/**
* synchronized关键字
* 对某个对象加锁
*/
public class T {
private int count = 10;
public void m() {
synchronized(this) { //任何线程要执行下面的代码,必须先拿到this的锁
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
}
}
三、执行方法时每次都加锁,直接对方法名进行加锁
/**
* synchronized关键字
* 对某个对象加锁
*/
public class T {
private int count = 10;
public synchronized void m() { //等同于在方法的代码执行时要synchronized(this)
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
}
四、当锁定静态方法时,由于静态方法不需要通过对象可以直接进行调用,因此锁定静态方式时等同于synchronized(对象名.class)
/**
* synchronized关键字
* 对某个对象加锁
*/
public class T {
private static int count = 10;
public synchronized static void m() { //这里等同于synchronized(T.class)
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
public static void mm() {
synchronized(T.class) { //考虑一下这里写synchronized(this)是否可以?
count --;
}
}
}
面试注意:
- synchronized并不是对代码片段进行加锁,而是对对象进行加锁!
- 一个synchronized代码块相当于一个原子操作,是不可分的,在线程在执行该代码块的时候,是不可以被打断的,只有当该线程执行完的时候,才能够继续执行同一段代码。