线程同步 synchronized

线程同步

什么是线程同步?

我们可以在计算机上运行各种计算机软件程序。每一个运行的程序可能包括多个独立运行的线程(Thread)。 线程(Thread)是一份独立运行的程序,有自己专用的运行栈。线程有可能和其他线程共享一些资源,比如,内存,文件,数据库等。 

多个线程同时读写同一份共享资源的时候,可能会引起冲突。这时候,我们需要引入线程“同步”机制即各位线程之间要有个先来后到,不能一窝蜂挤上去抢作一团。 

同步这个词是从英文synchronize(使同时发生)翻译过来的。我也不明白为什么要用这个很容易引起误解的词。既然大家都这么用,咱们也就只好这么将就。 线程同步的真实意思和字面意思恰好相反。

线程同步的真实意思,其实是“排队”:几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作。

 因此,关于线程同步,需要牢牢记住四点:

  1. 线程同步就是线程排队同步就是排队。线程同步的目的就是避免线程“同步”执行。这可真是个无聊的绕口令。 
  2. “共享”这两个字。只有共享资源的读写访问才需要同步。如果不是共享资源,那么就根本没有同步的必要。 
  3. 只有“变量”才需要同步访问变量需要同步,常量不需要(常量存放于方法区)。如果共享的资源是固定不变的,那么就相当于“常量”,线程同时读取常量也不需要同步。至少一个线程修改共享资源,这样的情况下,线程之间就需要同步。 
  4. 多个线程访问共享资源的代码有可能是同一份代码,也有可能是不同的代码;无论是否执行同一份代码,只要这些线程的代码访问同一份可变的共享资源,这些线程之间就需要同步。

并发问题

并发:同一个对象多个线程同时操作

例子:

1.上万人同时抢100张票

如果每个人都买成功了,那么后台票数就会变成负数,出错。

实际生活中也许会显示“你的手慢了”等表示你没有抢到

2.两个银行同时取钱

比如手机和柜台上都可以取钱,你卡上有500万,你想取300万,你媳妇想去500万,你俩同时去取,你媳妇在柜台上取,你在手机上操作的。你们取钱时都发现余额是500万,如果你们两个人都可以取出来,那么银行卡余额就是负的了,这是错误的情况。所以说你和你媳妇一定会形成一个排队的关系,有先后顺序的去取。

3.食堂排队打饭

现实生活中,我们会遇到”同一个资源,多个人都想使用”的问题,比如,食堂排队打饭,每个人都想吃饭,但窗口是有限的,最天然的解决办法就是:排队   一个个来.

                 

什么时候需要线程同步?

  • 处理多线程问题时,多个线程访问同一个对象(即并发问题),并且某些线程还想修改这个对象。这时候我们就需要线程同步
  • 线程同步其实就是一种等待机制,多个需要同时访问此对象的线程进入这个对象的等待池形成队列,等待前面线程使用完毕,下一个线程再使用(就是排队,一个一个来)。

如何实现线程同步? 

队列和锁(synchronized)

实现线程同步队列

 队列锁     ------>    同步,解决线程不安全的问题

1. 队列:就是排队

几个线程之间要排队,一个一个对共享资源进行操作,而不是同时进行操作。

2. 锁  synchronized

每个对象本身都有一把锁(sleep不会释放锁)

比如一个景点里只有一个厕所,很多人都要去上厕所,所有人都在排队上厕所,这就已经形成队列了, 队列要保证安全,比如你进去了,然后如果厕所门没关,那么后面队列里的人就都进去了,这样这个厕所就不安全了。于是乎,厕所门上都会有一把锁,一个人进去了,然后就把门锁上,锁上之后,后面的人就进不去了,前面的人方便完之后,再把锁打开,然后下一个人才能继续使用锁,如此循环,这样才能保证里面安全。

由于同一进程的多个线程共享同一块存储空间,在带来方便的同时,也带来了访问冲突问题,为了保证数据在方法中被访问时的正确性,在访问时加入锁机制   synchronized ,当一个线程获得对象排它锁,独占资源,其他线程必须等待使用后释放锁即可。

但是锁存在以下问题:鱼和熊掌不可兼得,性能与安全不可兼得,必定会损失性能。

  • 一个线程持有锁会导致其他所有需要此锁的线程挂起;
  • 在多线程竞争下,加锁,释放锁,会导致比较多的上下文切换和调度延时,引起性能问题,损失性能
  • 如果一个优先级高的线程等待一个优先级低的线程释放锁,会导致优先级倒置,引起性能倒置问题。(比如一个想小便的人在等一个大便的人释放锁,本来小便只需要几秒,但现在却要等很久)
     

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

无霸哥

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值