多线程同步的实现方法究竟有哪些

多线程同步的实现方法有哪些

当使用多线程访问同一一个资源时非常容易出现线程安全的问题(例如,当多个线程同时对一个数据进行修改是,会导致某些线程对数据的修改丢失)因此,需要蚕蛹同步机制来解决这种问题,java主要提供了3中实现同步机制的方法:
( 1 ) synchronize关键字
在java语言中,每个对象都有一个对象锁与之相关联,该锁表明对象在任何时候只允许被一个线程所拥有,当一 个线程调用对象的一段synchronize代码时需要先获取这个锁,然后去执行相应的代码,执行结束后,释放锁.
1) Synchronize关键字主要有两种用法(synchronize方法和sychonine块),此外该关键字还可以作用于静态方法类或某个实例,但这都对程序的效率有很大的影响,sychonie方法在方法的声明前假如sychronize关键字示例如下:
public synchronized void mutithradAccess();
只要把多个线程对类需要被同步的资源的操作放到mutiThreadAccess( )方法中,就能保证这个方法在同一时刻只能被一一个线程访问,从而保证了多线程访问的安全性.然而,当一个方法的方法体规模非常大时,把该方法声明为synchronize会大大影响程序的执行效率,为了提高程序的效率,Java提供synchronize块

2 ) synchronize块. Synchronize块既可以把任意的代码段声明为synchronize,也可以指定上锁的对象,有非常高的灵活性其用法如下:
synchronized (syncObject){
//访问syncObject的代码
}

( 2 ) wait( )方法与notify( )方法
当使用synchronize来修饰某个共享资源时,如果线程AI在执行synchronize代码,另外一个线程A2也要同时执行同一对象的同一synchronize代码时,线程A2将要等到线程A1执行完成后,才能继续执行在这种情况下可以使用wait( )方法和notify( )方法.
在synchronized代码被执行期间,线程可以调用对象
的wait()方法,释放对象锁,进人等待状态,并且可以调
用notify( )方法或notifyAl( )方法通知正在等待的其他线程。notify( )方法仅唤醒一个线程(等待队列中的第一个线程)并允许它去获得锁, ntifyAIl( )方法唤醒所有等待这个对象的线程并允许它们去获得锁(并不是让所有唤醒线程都获取到锁,而是让它们去竞争.

(3)Lock
JIDK 5新增加了接口以及它的一个实现类ReentrantLock(重人锁),Lock也可以用来实现多线程的同步,具体而言,它提供了如下一些方法来实现多线程的同步:
1) lock(以阻塞的方式获取锁,也就是说,如果获取
到了锁,立即返回;如果别的线程持有锁,当前线程等待,直到获取锁后返回。

2 ) tryLock().以非阻塞的方式获取锁。只是尝试性
地去获取一-下锁 ,如果获取到锁,立即返回true,否则,立即返回falseo

3 ) tryLock(long timeout, TimeUnit unit)。 如果获取了锁,立即返回true ,否则会等待参数给定的时间单元,在等待的过程中, 如果获取了锁,就返回true ,如果等待超时,返回false
4 ) lockInterruptibly().如果获取了锁,立即返回;
如果没有获取锁,当前线程处于休眠状态,直到获得锁,或者当前线程被别的线程中断(会收到
InteruptedException异常)。它与lock( )方法最大的
区别在于如果Iock( )方法获取不到锁,会一直处于阻塞状态,且会忽略m .tenupt( )方法,示例如下:

public class Test {
public static void main(String[] args) throws InterruptedExceptioni
final Lock lock = new ReentrantLock() ;
lock. lock() ;
Thread thread = new Thread (new Runnable() {
@Override
public void run() {
try{
lock. lockInterruptibly() ;
lock.lock();//编译器报错
} catch (InterruptedException e) {
System. out. println(" interrupted") ;
}
}
});
thread. start() ;
thread. interrupt() ;
Thread. sleep( millis: 1) ;
}
}

程序运行结果如下: interrupted.
如果把lock. lockIntemlptibly( )替换为lock. lock 0,
编译器将会提小lock. lock 0 catch代码块无效,这是因为lock. lock( )不会抛出异常,由此可见lock0方法会忽略interrupt( )引发的异常

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

秋风清,秋月明。落日夕阳一片红

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

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

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

打赏作者

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

抵扣说明:

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

余额充值