synchronized
synchronized 是 Java 中的一个关键字, 是一种同步锁 ,它修饰的对象主要有 4 种 .
- 修饰一个代码块: 大括号括起来的代码, 作用于调用的对象
- 修饰方法:整个方法, 作用于调用对象
- 修饰静态方法:整个静态方法, 作用于 所有对象
- 修饰类: 括号括起来部分, 作用于 所有对象
代码示例 1 :
package com.mmall.concurrency.example.sync;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j
public class SynchronizedExample1 {
// 修饰一个代码块
public void test1(int j) {
synchronized (this) {
for (int i = 0; i < 10; i++) {
log.info("test1 {} - {}", j, i);
}
}
}
// 修饰一个方法
public synchronized void test2(int j) {
for (int i = 0; i < 10; i++) {
log.info("test2 {} - {}", j, i);
}
}
}
main 函数 测试 synchronized 修饰一个方法
public static void main(String[] args) {
SynchronizedExample1 example1 = new SynchronizedExample1();
SynchronizedExample1 example2 = new SynchronizedExample1();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
example1.test2(1);
});
executorService.execute(() -> {
example1.test2(1);
});
}
运行结果
main 函数 测试 synchronized 修饰一个代码块
public static void main(String[] args) {
SynchronizedExample1 example1 = new SynchronizedExample1();
// SynchronizedExample1 example2 = new SynchronizedExample1();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
example1.test1(1);
});
executorService.execute(() -> {
example1.test1(1);
});
}
运行结果
小结
如果一个方法内部是一个完整的同步代码块 , 那么它和 用 synchronized
修饰的一个方法时等同的 . 修饰一个方法和修饰代码块都是作用于调用对象的
代码示例2
package com.mmall.concurrency.example.sync;
import lombok.extern.slf4j.Slf4j;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
@Slf4j
public class SynchronizedExample2 {
// 修饰一个类
public static void test1(int j) {
synchronized (SynchronizedExample2.class) {
for (int i = 0; i < 10; i++) {
log.info("test1 {} - {}", j, i);
}
}
}
// 修饰一个静态方法
public static synchronized void test2(int j) {
for (int i = 0; i < 10; i++) {
log.info("test2 {} - {}", j, i);
}
}
public static void main(String[] args) {
SynchronizedExample2 example1 = new SynchronizedExample2();
SynchronizedExample2 example2 = new SynchronizedExample2();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
example1.test1(1);
});
executorService.execute(() -> {
example2.test1(2);
});
}
}
main 函数 测试 synchronized 修饰一个静态方法
public static void main(String[] args) {
SynchronizedExample2 example1 = new SynchronizedExample2();
SynchronizedExample2 example2 = new SynchronizedExample2();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
example1.test2(1);
});
executorService.execute(() -> {
example2.test2(2);
});
}
运行结果
main 函数 测试 synchronized 修饰一个类
public static void main(String[] args) {
SynchronizedExample2 example1 = new SynchronizedExample2();
SynchronizedExample2 example2 = new SynchronizedExample2();
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(() -> {
example1.test1(1);
});
executorService.execute(() -> {
example2.test1(2);
});
}
运行结果
小结
当一个需要执行的代码部分, 都是被synchronized
修饰的一个类锁包裹的时候 , 它和 synchronized
修饰的一个静态方法时等同的 .
原子性对比
synchronized 不可中断锁, 适合竞争不激烈, 可读性好 .
一旦代码执行到synchronized 作用范围之内的时候 ,是必须等待代码执行完毕的Lock :可中断的锁, 调用 unlock 即可 . 多样化同步, 竞争激烈也能维持常态
Atomic 竞争激烈的时候也能维持常态, 比 Lock 性能还要好, 但是只能同步一个值 .
.