动力节点首页 全国咨询热线:400-8080-105

绑定手机号,登录
手机号

验证码

微信登录
手机号登录
手机号

验证码

30天自动登录
微信登录与注册
微信扫码登录与注册

扫码关注微信公众号完成登录与注册
手机号登录
首页 > 文章

实现线程同步的3种方法

05-21 11:06 365浏览
举报 T字号
  • 大字
  • 中字
  • 小字

Java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时,将会导致数据不准确,相互之间产生冲突,因此,实现线程同步以避免在该线程没有完成操作之前,被其他线程调用,从而保证了该变量的唯一性和准确性。一般情况下,实现线程同步有以下3种方法:

1.synchronized关键字

1)Synchronized修饰整个方法

例:
public synchronized void set(){}

注意:synchronized也可以修饰静态方法,如果此时调用这个方法,将会锁住整个类。

2) synchronized修饰具体的代码块

public void save(){

synchronized (this){
  count += money
}
}

PS : 同步是一种高开销的操作,因此,应该尽量减少同步的内容。一般情况下不需要同步整个方法,只需同步对应的代码块即可。

2.Lock

小编认为Lock与Synchronized比较起来,Lock的优点还是比较多的。

如果一个代码块被synchronized关键字修饰,当一个线程执行该代码块时,其他的线程便只能一直等待直到占有锁的线程释放锁。那么,什么情况下占有锁的线程会释放锁呢 ?

  • 占有锁的线程执行完了该代码块,然后释放。
  • 占有锁的线程执行发生了异常,此时JVM会让线程自动释放锁。
  • 占有锁的线程进入waiting状态从而释放锁,

既然synchronized如此方便,可以轻松实现对资源的同步互斥访问。那么,为什么还需要Lock呢 ?考虑以下3种情况:

Case 1 :

在使用synchronized关键字时,假如占有锁的线程由于要等待IO或者其他原因(比如调用sleep()方法)被阻塞了,但是又没有使释放锁,那么其他的线程就只能一直等待。

Case 2:

多个线程读写文件时,读和写操作会发生冲突,写和写操作也会发生冲突,但是,读和读操作不会发生冲突。所以使用synchronized关键字就会导致一个问题:无法实现多个线程同步进行读操作。这就会极大的影响程序的执行效率。

Case 3:

我们可以通过Lock得知线程有没有成功获取锁,但是synchronized无法做到。

以上三个Case中所描述的问题,Lock都可以解决,现在知道为什么会有Lock 这个东西了吧哈哈!

下面我们简单来说一下使用Lock实现线程同步的方法:

lock.lock() 加锁;lock.unlock() 释放锁。

public class Count{
Lock lock = new ReentrantLock();
public void save(){
for(int i=0;i<10;i++)
{ count++;
System.out.println("count:"+count);
}
lock.unlock();
}
}

3.volatile关键字

1)volatile是变量修饰符,其修饰的变量具有可见性。

可见性就是说一旦某个线程修改了被volatile修饰的变量,它会保证修改的值会立即被更新到主存,当有其他线程需要读取的时候,可以立即获取修改之后的值。

在Java中为了加快程序的运行效率,对一些变量的操作通常是在该线程的寄存器或CPU缓存上进行的,之后才会同步到主存中,而加了volatile修饰符的变量则是直接读写主存。

2)volatile可以禁止指令重排

指令重排是指编译器或者CPU为了提高程序的运行效率,可能会对输入的代码进行优化,它不保证各个语句的执行顺序同代码中的顺序一致,但是它会保证程序最终执行结果和代码中的执行结果是一致的,应用条件是单线程条件,对于并发多线程的场景下,指令重排会产生不确定的结果。

想要了解更多的线程相关的知识,我们可以观看动力节点在线的Java多线程视频课程,名师讲解,帮助我们攻克Java多线程的难关。

0人推荐
共同学习,写下你的评论
0条评论
代码小兵696
程序员代码小兵696

118篇文章贡献392976字

相关课程 更多>

作者相关文章更多>

推荐相关文章更多>

Java面试题及答案整理

代码小兵66904-21 20:01

6道经典算法面试题

杨晶珍05-12 16:39

简述Spring MVC的核心组件

代码小兵49806-11 16:26

SpringMVC 中的组件

代码小兵49806-11 16:28

Spring常见面试题

代码小兵92504-17 16:07

发评论

举报

0/150

取消