视频地址:https://www.bilibili.com/video/BV1Jx411a7Dp
synchronized(对象)
对括号内的对象加锁,任何线程要执行synchronized
代码块中的代码,都必须要先拿到该对象的锁,当执行完毕时,该线程释放锁,锁可以被其他线程获取。1
2
3
4
5
6
7
8
9
10
11public class T {
private final Object lock = new Object(); // 锁对象
public void m() {
synchronized (lock) { // 任何线程要执行下面的代码,都必须先拿到lock锁,锁信息记录在堆内存对象中的,不是在栈引用中
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
// 当上述synchronized代码块执行完毕后,锁就会被释放,然后被其他线程获取
}
}synchronized(this)
可以直接在实例方法中使用
synchronized(this)
,避免每次都要创建一个对象。1
2
3
4
5
6
7
8public class T {
public void m() {
synchronized (this) { /
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
}
}synchronized修饰整个方法
1
2
3
4
5
6public class T {
public synchronized void m() {
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
}synchronized
关键字加在静态方法上,相当于synchronized(T.class)
1
2
3
4
5
6
7
8
9
10
11
12
13
14public class T {
public static synchronized void m1() { // 等同于 synchronized (T.class) {
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
// m1()方法与m2()方法等价
public static void m2() {
synchronized (T.class) {
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
}
}使用实例
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17public class Test implements Runnable{
private int count = 10;
public /*synchronized*/ void run() {
count--;
System.out.println(Thread.currentThread().getName() + " count = " + count);
}
public static void main(String[] args) {
Test t = new Test();
for (int i = 0; i < 5; i++) {
new Thread(t).start(); // 再这里new的所有线程的锁住的是同一个上边的t对象
}
}
}1
2
3
4
5Thread-1 count = 8
Thread-2 count = 7
Thread-0 count = 8
Thread-3 count = 6
Thread-4 count = 5未使用synchronized时,每个线程在执行count–操作和输出操作之间都可能被其它线程打断。
使用synchronized后
1
2
3
4
5Thread-0 count = 9
Thread-1 count = 8
Thread-2 count = 7
Thread-3 count = 6
Thread-4 count = 5