java 多线程同步机制

、为什么需要多线程同步

我们来举一个例子:某餐厅的卫生间很小,几乎只能容纳一个人如厕。为了保证不受干扰,如厕的人进入卫生间,就要锁上房门。我们可以把卫生间想象成是共享的资源,而众多需要如厕的人可以被视作多个线程。假如卫生间当前有人占用,那么其他人必须等待,直到这个人如厕完毕,打开房门走出来为止。这就好比多个线程共享一个资源的时候,是一定要分出先来后到的。
这里,最关键的就是卫生间的门。其实卫生间的门担任的是资源锁的角色,只要如厕的人锁上门,就相当于获得了这个锁,而当他打开锁出来以后,就相当于释放了这个锁。

二、什么时候需要多线同步?

需要使用多个线程处理同一个问题。(例如:要求1000个线程对一个变量加1)

三、如何理解同步这个词?

举一个例子:小明和小花为一组,参加双人绑腿赛跑,小明跑的快,小花跑的慢,那么为了到达终点,步调必须一致。在java中,如果使用多线程处理同一个问题,必然存在一个快,一个慢;既然处理同一个问题,那么就会在处理过程中交流(例如:交流一些中间变量);这个时候就需要同步,统一步伐。
       多线程同步机制是为了实现java中的可见性(指线程之间的可见性,一个线程修改的状态对另一个线程是可见的)。
         如果有A,B线程,A线程修改了某一个变量i的值,B线程需要获取A线程修改过的i。那么我们如何知道A线程已经修改了i ? 为了实现在任意的时候都可以获得该值,不必在A线程结束之后,我们可以使用在A线程修改值后使用wait(),在B线程获取之后使用notify()唤醒A线程。 
         也就是java的同步机制为的是实现一个线程的修改状态可以在任意时刻对另一线程可见(当然这需要编程者自己控制什么时候),这也就不难理解java为了提供了Synchronized,wait,sleep,join,yield等。

四、同步什么?

在Java程序运行时环境中,JVM需要对两类线程共享的数据进行协调:
1)保存在堆中的实例变量
2)保存在方法区中的类变量
这两类数据是被所有线程共享的。(程序不需要协调保存在Java栈当中的数据。因为这些数据是属于拥有该栈的线程所私有的)
同步的内容即是多线程公有的资源。

五、Java如何实现多线程同步?

为了解决多线程竞争资源,在java虚拟机中,使每个对象和类都与一个监视器(也就是上面所说的锁)相关联用来保护公有资源。
注:
1.如果一个对象没有实例变量,或者一个类没有变量,相关联的监视器就什么也不监视。
2.什么是监视器?
监视器好比一做建筑,它有一个很特别的房间,房间里有一些数据,而且在同一时间只能被一个线程占据,进入这个建筑叫做"进入监视器",进入建筑中的那个特别的房间叫做"获得监视器",占据房间叫做"持有监视器",离开房间叫做"释放监视器",离开建筑叫做"退出监视器。

如果线程获取了监视器,那么在释放之前,其他线程不可获取该对象的监视器。而对于同步的方法或者代码块来说,必须获得对象锁才能够进入同步方法或者代码块进行。
Java中采用synchronized获取对象或类的监视器(锁定)。
Synchronized的用法有两种:
1.修饰方法。修饰非静态方法,对象锁为method所在的对象(也就是this);如果是静态方法,对象锁即指method所在的Class对象(唯一)(又称为类锁);
2.修饰代码块。对象锁即指synchronized(abc)中的abc。
注:
1.类锁实际上用对象锁来实现。
当虚拟机装载一个class文件的时候,它就会创建一个java.lang.Class类的实例。当锁住一个类的时候,实际上锁住的是那个类的Class对象。
2.锁的实现。
对于每一个对象,java虚拟机维护一个加锁计数器,线程每获得一次该对象,计数器就加1,每释放一次,计数器就减 1。计数器0时,锁释放。
3.锁的其他注意事项:
(1)每当使用synchronized,JVM都会自动锁上对象或者类;
(2)在JVM中,所有被加载的类都有唯一的类对象;
(3)一个线程可以多次对同一个对象上锁。

当然仅有synchronized不能完全实现同步机制,要不然java也可能提供wait,sleep,join,yield等。(wait的介绍可以见另一篇博文)

参考:

java的锁机制
http://blog.csdn.net/yangzhijun_cau/article/details/6432216
监视器–JAVA同步基本概念
http://ifeve.com/monitors-java-synchronization-mechanism/
经典解释监视器和对象锁
http://blog.csdn.net/fenglibing/article/details/1483930
Java中Volatile关键字详解
http://www.cnblogs.com/zhengbin/p/5654805.html
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

nachifur

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

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

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

打赏作者

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

抵扣说明:

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

余额充值