【线程安全】【线程通信】【Java】synchronized锁讲解,锁方法和锁住变量,隐式锁和显式锁Lock,信息同步

线程安全和线程同步及时读取问题

线程安全问题

在多个线程同时操作同一个对象(变量)的时候会在自己的栈内存里面进行,出现这样的情况的时候,如果线程没有及时的把自己操作之后的结果,同步到堆内存里面,就会导致最后的变量并不是我们希望得到的操作之后的结果,因此就发生了线程不安全的情况。为了解决这个问题,我们需要对于变量和线程进行同步。

而解决这个问题的思路就是锁,即当一个线程对于一个变量进行操作的时候,我们可以利用锁把这个变量锁起来,这样就可以保证一次只有一个线程在操作某个变量,进而保证了栈内存里面如果变量发生了改变,会把这个信息及时的更新到堆内存里面,这样所有的线程就会知道这个信息,进而保障了线程的安全问题。而之所以叫做synchronized(同步)也是因为这样的设置会导致没有抢占到资源的线程进入堵塞的状态,而在这个过程中实现了线程之间信息的同步。

线程同步及时更新读取问题

通常,锁的使用适合在存在有写和更改数据的场景里面,而只存在读写的场景的时候,数据之间的及时看见和更新,可以使用volatile来解决。这个一般存在的情况是,线程都会执行某种任务,线程内部可能是一个死循环,但是这个循环内的某个变量会需要及时的更新(可能其他的线程会对这个变量进行更改)这种情况下,我们的线程没有去修改任何的变量,但是需要及时的知晓变量的变化,使用锁的话,可能效率比较低,这个时候,就可以使用volatile解决这个问题。

线程安全问题的解决办法:锁

synchronized锁住某个变量(被操作的对象)

假如我们的线程都想要去操作Task里面的num这个变量,那么可以直接在里面写操作的时候,就把这个变量给锁住。其中锁后面的变量一样的,就是一把锁,一个时间内,持有这种锁的线程才能运行。锁里面是什么对象不重要,重要的是竞争的线程之间,分享的都是这同一个对象。

class Task{
   
	int num;
	public void add(){
   
	synchronized(this){
   num ++;}
	}
	public void multiple(){
   
	synchronized(this){
   num *= num;}	
	}

synchronized锁住某个对象的方法

这个直接在对象的方法前面加上synchronized关键词就ok啦,就像test做的那样

public class Test {
   
    public synchronized void test(Task obj){
   
        for (int i = 0; i < 20000; i++) {
   
            obj.num++;
        }
    }
    public static void main(String[] args) {
   
        Test t = new Test();
        Task ta = new Task();
        for (int i = 0; i < 5; i++) {
   
            new Thread(new Runnable(){
   
                @Override
                public void run
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值