🌿🌿🌿跟随博主脚步,从这里开始→博主主页🌿🌿🌿
- 欢迎大家:这里是我的学习笔记、总结知识的地方,喜欢的话请三连,有问题可以私信🌳🌳🌳
您的点赞👍、关注➕、收藏⭐️、评论📝、私信📧是我最大的支持与鼓舞!!!🌻🌻🌻
线程同步与对象锁
- 多线程的并发执行可以提高程序的效率,但是,当多个线程同时去访问同一个资源时,这可能引起线程冲突的情况。
- 计数器Counter类对象,它作为共享数据资源。
- 当两个操作运行在不同线程中,对同一个数据的两个操作就可能产生冲突。其原因是有些操作看起来是简单操作,但不是原子的, (原子操作:执行过程中,不能被线程调度器中断的操作)虚拟机需要用多个步骤完成。
- 如表达式:count++;
1)检索count的当前值。
2)为检索到的值加1。
3)增加1后的值存到count中。 - 对于Counter对象,两个线程A和B。线程A调用increment()方法,同时线程B也调用increment()方法。如果count的初值为0,它们交错的动作可能按下列顺序执行。
1)线程A:检索count的值0。
2)线程B:检索count的值0。
3)线程A:将count加1,count的结果为1。
4)线程B:将count加1,count的结果为1。
5)线程A:将结果存回count,count的值为1。
6)线程B:将结果存回count,count的值为1。 - 要防止多个线程同时访问同一资源产生冲突,就是防止多个线程同时执行共享对象的方法代码。程序中这样的代码称作临界区(critical section)。
- 为保证临界区中的代码在一段时间内只被一个线程执行,应在线程开始执行临界区代码时,给临界区加锁, 这样,其他线程在这个临界区被解锁之前,无法执行临界区的代码,在其被解锁之后,其他线程才可以锁定并执行其中的代码。
- Java的每个对象都有一个内在锁(intrinsic lock),有时也称作监视器锁(monitor lock)。
- 获得对象的内在锁是能够独占该对象访问权的一种方式。获得对象的内在锁与锁定对象是一样的。
- Java通过同步代码块实现内在锁,Java支持两种同步:
1)方法同步
2)块同步
线程同步与对象锁—方法同步
- 方法同步就是在定义方法时使用
synchronized
关键字修饰,被修饰的方法为同步方法,具体语法格式如下:
- 被synchronized修饰的方法在某一时刻只允许一个线程访问,访问该方法的其他线程都会发生阻塞,直到当前线程访问完毕后,其他线程才有机会执行该方法。
线程同步与对象锁—块同步
- 如果使用类库中的类或别人定义的类时,调用的方法没有使用synchronized关键字修饰,又要获得对象锁,可以使用下面的格式:
- lock是一个锁对象,它是同步代码块的关键。当某一个线程执行同步代码块时,其它线程将无法执行当前同步代码块,会发生阻塞,等当前线程执行完同步代码块后,其它的线程开始抢夺执行权,抢到执行权的线程将进入同步代码块,执行其中的代码。循环往复,直到共享资源被处理完为止。
- 这个过程就好比一个公用电话亭,只有前一个人打完电话出来后,后面的人才可以打。
- 下面代码利用非线程安全的Counter类作为计数器,为了在计数器递增的时候将计数器对象锁定,incrementCount()方法锁定Counter对象。
Counter counter = new Counter();
public void incrementCount(){
synchronized (counter){ // 锁定counter对象
// 执行需要同步的语句
counter.increment();
}
}
线程同步与对象锁—类锁
- 每个类也可以有类锁。类锁控制对类的synchronized static代码的访问。请看下面的例子。
public class SampleClass{
static int x, y;
static synchronized void increment(){
x++;
y++;
}
}
博主用心写,读者点关注,互动传真情,知识不迷路。