线程安全诱因: 1 存在共享数据, 2 存在多条线程同时操作共享数据 互斥锁的特性: 1 互斥性:只允许同一时间只有一个线程持有某个对象锁,保证同一时间只有一个线程对需要同步的代码块进行访问,互斥性也称为操作原子性 2 可见性:必须保证在锁被释放之前,对共享变量所做的修改,对后面获得该锁的另一个线程是可见的,否则另一个线程可能会使用本地缓存副本,引起不一致。 3 synchronizad 锁的不是代码,锁的是对象 锁分类: 1 对象锁:获取对象锁的两种方式(1)同步代码块 synchronizad(this),synchronizad(类实例对象),锁是小括号中的实例对象;(2)同步非静态方法synchronizad method(),锁是但前对象的实例对象。 2 类锁:获取对象锁的两种方式(1)同步代码块 synchronizad(Object.class),锁是小括号中的类;(2)同步静态方法static synchronizad method(),锁是但前对象的类。 总结: 1 有线程访问对象的同步代码块时,另外的线程可以访问该对象的非同步代码块; 2 若锁住的是同一个对象,一个线程访问对象的同步代码块时,另一个线程访问该同步代码块会被阻塞 3 若锁住的是同一个对象,一个线程访问对象的同步方法时,另一个线程访问该同步方法会被阻塞 4 若锁住的是同一个对象,一个线程访问对象的同步代码块时,另一个线程访问同步方法会被阻塞;反之亦然 5 同一个类的不同对象的对象锁,或不干扰; 6 类锁由于也是一种特殊的对象锁,因此,表现同上述1234一致,而由于一个类只有一把对象锁,所以同一个类的不同对象使用类锁将会是同步的; 7 类锁和对象锁互不干扰。
package com.mall.controllor.alene;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.SimpleTimeZone;
/**
* Created by 60341 on 2020/3/19.
*/
public class SyncThread implements Runnable{
@Override
public void run() {
String name = Thread.currentThread().getName();
if (name.startsWith("A")) {
async();
} else if (name.startsWith("B")) {
syncObjectBlock1();
} else if (name.startsWith("C")){
syncObjectMethod1();
} else if (name.startsWith("D")){
syncClassBlock1();
} else if (name.startsWith("E")){
syncClassMethod1();
}
}
//异步方法
private void async(){
System.out.println(Thread.currentThread().getName()+"_Async: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
try {
System.out.println(Thread.currentThread().getName()+"_Async_start: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"_Async_end: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//同步代码块:方法中有synchronized (this|object) {} --对象锁
private void syncObjectBlock1(){
System.out.println(Thread.currentThread().getName() + "_syncObjectBlock1: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
synchronized (this) {
try {
System.out.println(Thread.currentThread().getName() + "_syncObjectBlock1_start: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "_syncObjectBlock1_end: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//同步方法: synchronized修饰非静态方法 --对象锁
private synchronized void syncObjectMethod1(){
System.out.println(Thread.currentThread().getName()+"_syncObjectMethod1: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
try {
System.out.println(Thread.currentThread().getName()+"_syncObjectMethod1_start: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"_syncObjectMethod1_end: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//同步代码块:方法中有synchronized (object.class) {} --类锁
private void syncClassBlock1(){
System.out.println(Thread.currentThread().getName() + "_syncClassBlock1: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
synchronized (SyncThread.class) {
try {
System.out.println(Thread.currentThread().getName() + "_syncClassBlock1_start: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + "_syncClassBlock1_end: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//同步方法: synchronized修饰静态方法 --类锁
private synchronized static void syncClassMethod1(){
System.out.println(Thread.currentThread().getName()+"syncClassMethod1: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
try {
System.out.println(Thread.currentThread().getName()+"_syncClassMethod1_start: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+"_syncClassMethod1_end: " + new SimpleDateFormat(" HH:mm:ss").format(new Date()));
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
package com.mall.controllor.alene;
/**
* Created by 60341 on 2020/3/19.
*/
public class SyncDemo {
public static void main(String[] args) {
SyncThread syncThread = new SyncThread();
Thread A_thread1 = new Thread(syncThread,"A_thread1");
Thread A_thread2 = new Thread(syncThread,"A_thread2");
Thread B_thread1 = new Thread(syncThread,"B_thread1");
Thread B_thread2 = new Thread(syncThread,"B_thread2");
Thread C_thread1 = new Thread(syncThread,"C_thread1");
Thread C_thread2 = new Thread(syncThread,"C_thread2");
Thread D_thread1 = new Thread(syncThread,"D_thread1");
Thread D_thread2 = new Thread(syncThread,"D_thread2");
Thread E_thread1 = new Thread(syncThread,"E_thread1");
Thread E_thread2 = new Thread(syncThread,"E_thread2");
A_thread1.start();
A_thread2.start();
B_thread1.start();
B_thread2.start();
C_thread1.start();
C_thread2.start();
D_thread1.start();
D_thread2.start();
E_thread1.start();
E_thread2.start();
}
/*运行结果;
B_thread2_syncObjectBlock1: 11:06:35
A_thread1_Async: 11:06:35
A_thread2_Async: 11:06:35
A_thread1_Async_start: 11:06:35
A_thread2_Async_start: 11:06:35
C_thread1_syncObjectMethod1: 11:06:35
D_thread1_syncClassBlock1: 11:06:35
C_thread1_syncObjectMethod1_start: 11:06:35
B_thread1_syncObjectBlock1: 11:06:35
E_thread1syncClassMethod1: 11:06:35
D_thread2_syncClassBlock1: 11:06:35
E_thread1_syncClassMethod1_start: 11:06:35
C_thread1_syncObjectMethod1_end: 11:06:37
B_thread1_syncObjectBlock1_start: 11:06:37
A_thread2_Async_end: 11:06:37
A_thread1_Async_end: 11:06:37
E_thread1_syncClassMethod1_end: 11:06:37
D_thread2_syncClassBlock1_start: 11:06:37
B_thread1_syncObjectBlock1_end: 11:06:38
B_thread2_syncObjectBlock1_start: 11:06:38
D_thread2_syncClassBlock1_end: 11:06:38
D_thread1_syncClassBlock1_start: 11:06:38
B_thread2_syncObjectBlock1_end: 11:06:39
C_thread2_syncObjectMethod1: 11:06:39
C_thread2_syncObjectMethod1_start: 11:06:39
D_thread1_syncClassBlock1_end: 11:06:39
E_thread2syncClassMethod1: 11:06:39
E_thread2_syncClassMethod1_start: 11:06:39
C_thread2_syncObjectMethod1_end: 11:06:40
E_thread2_syncClassMethod1_end: 11:06:40
*/
}