线程同步代码块synchronized应用解析

线程同步代码块synchronized应用解析

多个线程同时操作同一个共享资源的时候可能会出现业务安全问题,成为线程安全问题

线程同步

让多个线程实现先后访问共享资源,就解决了安全问题

线程同步的核心思想

加锁,把共享资源进行上锁,每次只能一个线程进入,访问完毕后解锁,然后其他线程才能进来。

同步代码块

synchronized(临界资源对象){
	//原子操作
}

作用:把出现线程安全问题的核心代码给上锁
原理:每次只能一个线程进入,执行完毕后自动解锁,其他线程才可以进来执行
如果想要实现线程同步,需要不同的线程抢占同一个对象锁标记(对临界资源加锁)才能达到互斥目的,从而实现线程同步,数据安全。

线程执行过程中,遇到同步代码块,只有获取临界资源对象的锁标记才能执行同步代码块{}中的内容,并且将{}中所有的程序全部执行完,才能释放拥有的锁标记,如果一个线程试图获取锁标记时,使得锁标记被其他线程占用,则当前线程进入阻塞状态(Blocked),等待获取锁标记,只有获取了等待对象的锁标记并获取了cpu的时间片才能执行同步代码块{}中的内容。
【线程同步小demo】

public class Test {
    public static void main(String[] args) throws InterruptedException {
      String str = "呵呵";
      String str1 = "嘿嘿";
      Thread t1 = new ThreadA(str,"t1");
      Thread t3 = new ThreadA(str1,"t3");
      Thread t2 = new ThreadB(str,"t2");
      t1.start();
      t2.start();
      t3.start();
      t3.join();
      t1.join();
      t2.join();
    }
}
class ThreadA extends Thread{
    String str = null;
    public ThreadA(String str,String name) {
        super(name);
        this.str = str;
    }
    public void run(){
        synchronized (str) {
            System.out.println(Thread.currentThread().getName());
            try {
                Thread.sleep(50000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("");
        }
    }
}
class ThreadB extends Thread{
    String str = null;
    public ThreadB(String str,String name) {
        super(name);
        this.str = str;
    }
    public void run(){
        synchronized (str) {
            System.out.println(Thread.currentThread().getName());
            System.out.println("");
        }
    }
}

------------------------------------------
t1
t3
过了几秒后
t2

程序解析:

线程 t1 和线程 t2 内部的 str 指向的是同一个对象"呵呵",而线程 t3 内部的str指向的是"嘿嘿"。

程序开始运行时,调用 join() 方法后,t1 t2 t3 优先于main线程执行,t1 先抢到cpu时间片进行执行,遇到synchronized 同步代码块,获得str的 锁标记,此时"呵呵"锁标记被占,t1 进入休眠状态,释放cpu时间片但并不释放锁标记。

这时,哪怕 t2 获得了cpu时间片,t2 由于没有"呵呵"的锁标记,所以只能进入阻塞状态

此时 t3 获得”嘿嘿"锁标记,进行执行,执行完毕后释放锁标记,t3 执行完毕。

​t1 从睡眠中苏醒后执行完代码块,释放”呵呵“锁标记,然后 t2 才能占有”呵呵“锁标记进行后续代码执行。

  • 5
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值