同步锁 synchronized 线程安全

线程安全诱因:
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
       */
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值