1 Synchronized
1.1 作用
一句话概括:
- 能够保证
同一时刻
最多只有一个
线程执行该段代码,以达到保证并发安全的效果。
1.1 不使用并发手段的后果
public class DisappearRequest1 implements Runnable {
static DisappearRequest1 instance = new DisappearRequest1();
static int i = 0;
public static void main(String[] args) throws InterruptedException {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println(i);
}
@Override
public void run() {
for (int j = 0; j < 100000; j++) {
i++;
}
}
}
2 Synchronized
的两个用法
2.1 对象锁
包括方法锁
(默认锁对象为this当前实例对象)和同步代码块锁
(自己指定锁对象)
代码块形式:手动指定锁对象
方法锁形式: synchronized 修饰普通方法,锁对象默认是 this
/**
* @Description 对象锁案例1,代码块形式
* @Author tzb
* @Date 2020/12/16 22:56
* @Version 1.0
**/
public class SycchronizedObjecfCodeBlock2 implements Runnable {
static SycchronizedObjecfCodeBlock2 instance = new SycchronizedObjecfCodeBlock2();
@Override
public void run() {
synchronized (this) {
System.out.println("我是对象锁的代码块形式,我叫" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "运行结束");
}
}
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
}
public class SycchronizedObjecfCodeBlock2 implements Runnable {
static SycchronizedObjecfCodeBlock2 instance = new SycchronizedObjecfCodeBlock2();
Object lock1 = new Object();
Object lock2 = new Object();
@Override
public void run() {
synchronized (lock1) {
System.out.println("我是lock1,我叫" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " lock1运行结束");
}
synchronized (lock2) {
System.out.println("我是lock2,我叫" + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " lock2运行结束");
}
}
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
}
2.1.1 调试技巧 - 看线程的生命周期
public class SycchronizedObjecfCodeBlock2 implements Runnable {
static SycchronizedObjecfCodeBlock2 instance = new SycchronizedObjecfCodeBlock2();
@Override
public void run() {
synchronized (this) {
System.out.println("我是对象锁的代码块形式,我叫 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 运行结束");
}
}
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
}
-
断点处右击
-
All
: 会把整个 jvm停止,包括其他的线程 -
thread
: 只会停止当前的线程
-
线程0: Runnable
-
线程1
2.1.2 对象锁的形式2-普通方法锁
/**
* @Description 对象锁实例2-方法锁
* @Author tzb
* @Date 2021/1/4 22:55
* @Version 1.0
**/
public class SynchronizedObjectMethod3 implements Runnable {
static SynchronizedObjectMethod3 instance = new SynchronizedObjectMethod3();
public static void main(String[] args) {
Thread t1 = new Thread(instance);
Thread t2 = new Thread(instance);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
@Override
public void run() {
method();
}
public synchronized void method(){
System.out.println("我是对象锁的方法修饰符形式,我叫 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 运行结束");
}
}
2.2 类锁
指 synchronized
修饰静态
的方法或指定为 Class对象
2.2.1 类锁的形式1- 静态方法锁
- 不加
static
public class SynchronizedClassStatic4 implements Runnable {
static SynchronizedClassStatic4 instance1 = new SynchronizedClassStatic4();
static SynchronizedClassStatic4 instance2 = new SynchronizedClassStatic4();
@Override
public void run() {
method();
}
public synchronized void method() {
System.out.println("我是类锁的第一种形式:static形式,我叫 " + Thread.currentThread().getName());
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + " 运行结束");
}
public static void main(String[] args) {
Thread t1 = new Thread(instance1);
Thread t2 = new Thread(instance2);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
}
2.2.2 类锁的形式2- .class
- 反例
this
public class SynchronizedClassClass5 implements Runnable{
static SynchronizedClassClass5 instance1 = new SynchronizedClassClass5();
static SynchronizedClassClass5 instance2 = new SynchronizedClassClass5();
@Override
public void run() {
}
private void method() throws InterruptedException {
synchronized (this){
System.out.println("我是类锁的第二种形式:synchronized(*.class),我叫" +Thread.currentThread().getName());
Thread.sleep(3000);
System.out.println(Thread.currentThread().getName()+" 执行完毕");
}
}
public static void main(String[] args) {
Thread t1 = new Thread(instance1);
Thread t2 = new Thread(instance2);
t1.start();
t2.start();
while (t1.isAlive() || t2.isAlive()) {
}
System.out.println("finished");
}
}
- 修改为
.class