java 锁升级_java线程中synchronized锁和升级替换锁

在之前的文章《java中关于线程安全问题的详细说明》中其实有讲到关于线程的安全问题,那么就引入了一个关于安全锁synchronized的两种用法,那么其实在synchronized的两种用法中还是会存在一定的问题。

举一个例子:

我们假定一个生产者,一个消费者,在对烤鸭这个资源进行生产和消费,那么这个时候可以正常的使用到synchronized的两种用法,但是如果当多个生产者和多个消费者来进行轮流替换时,也就是生产者生产了一只烤鸭的情况下消费者才能消费一只烤鸭,然后再允许生产者生产第二只烤鸭,消费者再消费第二只烤鸭,以此类推,这个时候就会导致程序出现死锁的情况。

这时我们就需要引入两个方法notify和notifyAll

notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义,而且while判断标记+notify会导致死锁。

notifyAll:解决了本方线程一定会唤醒对方线程的问题。

所以这个时候我们就能很好的解决了关于多生产者和多消费者之间的安全存在问题。

if判断标记,只有一次,会导致不该运行的线程运行了,出现了数据错误的情况。

while判断标记,解决了线程获取执行权后,是否要运行!

例如:

class ky{

private String name;

private int sl=1;

private boolean flag=false;

public synchronized void set(String name){

while(flag)

try {

this.wait();

} catch (InterruptedException e) {

}

this.name=name+sl;

sl++;

System.out.println(Thread.currentThread().getName()+”…生产者…”+this.name);

flag=true;

notifyAll();

}

public synchronized void out(){

while(!flag)

try {

this.wait();

} catch (InterruptedException e) {

}

System.out.println(Thread.currentThread().getName()+”…消费者…”+this.name);

flag=false;

notifyAll();

}

}

class scz implements Runnable{

private ky r;

scz(ky r){

this.r=r;

}

public void run(){

while(true){

r.set(“烤鸭”);

}

}

}

class xfz implements Runnable{

private ky r;

xfz( ky r){

this.r=r;

}

public void run(){

while(true){

r.out();

}

}

}

public class ProducerConsumerDemo {

public static void main(String[] args){

ky k=new ky();

scz s=new scz(k);

xfz x=new xfz(k);

Thread t0=new Thread(s);

Thread t1=new Thread(s);

Thread t2=new Thread(x);

Thread t3=new Thread(x);

t0.start();

t1.start();

t2.start();

t3.start();

}

}

那么这样就解决了死锁的问题,可是这样的思想在java中是比较落后的,因为在java1.5即java5.0之后运用java的面向对象的思想,重新对安全锁这个概念进行了升级优化。

如下:

import java.util.concurrent.locks.*;

class ky{

private String name;

private int sl=1;

private boolean flag=false;

//创建锁对象

Lock lock=new ReentrantLock();

//通过已有的锁获取该锁上的监视器对象。

Condition l1 = lock.newCondition();

Condition l2 = lock.newCondition();

public void set(String name){

lock.lock();

try {

while(flag)

try {

l1.await();

} catch (InterruptedException e) {

}

this.name=name+sl;

sl++;

System.out.println(Thread.currentThread().getName()+”…生产者5.0…”+this.name);

flag=true;

l2.signal();

}

finally{

lock.unlock();

}

}

public void out(){

lock.lock();

try {

while(!flag)

try {

l2.await();

} catch (InterruptedException e) {

}

System.out.println(Thread.currentThread().getName()+”…消费者5.0…”+this.name);

flag=false;

l1.signal();

}

finally{

lock.unlock();

}

}

}

class scz implements Runnable{

private ky r;

scz(ky r){

this.r=r;

}

public void run(){

while(true){

r.set(“烤鸭”);

}

}

}

class xfz implements Runnable{

private ky r;

xfz( ky r){

this.r=r;

}

public void run(){

while(true){

r.out();

}

}

}

public class ProducerConsumerDemo {

public static void main(String[] args){

ky k=new ky();

scz s=new scz(k);

xfz x=new xfz(k);

Thread t0=new Thread(s);

Thread t1=new Thread(s);

Thread t2=new Thread(x);

Thread t3=new Thread(x);

t0.start();

t1.start();

t2.start();

t3.start();

}

}

那么jdk1.5以后将同步和锁封装成了对象,并将操作锁的隐式方式定义到了该对象中,将隐式动作编程了显示动作,既使用Lock和Condition接口来进行优化。

Lock接口:它的出现替代了同步代码块或者同步函数,将同步的隐式锁操作变成显示锁操作,同时更为灵活,可以一个锁上加上多组监视器。

lock():获取锁。

unlock():释放锁,通常需要定义finally代码块中。

Condition接口:它的出现替代了Object中的wait、notify和notifyAll方法。将这些监视器方法单独进行了封装,变成Condition监视器对象,可以任意锁进行组合。

await()相当于wait()

signal()相当于notify()

signalAll()相当于notifyAll()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源】:包含前端、后端、移动开发、操作系统、人工智能、物联网、信息化管理、数据库、硬件开发、大数据、课程资源、音视频、网站开发等各种技术项目的源码。包括STM32、ESP8266、PHP、QT、Linux、iOS、C++、Java、MATLAB、python、web、C#、EDA、proteus、RTOS等项目的源码。 【项目质量】:所有源码都经过严格测试,可以直接运行。功能在确认正常工作后才上传。 【适用人群】:适用于希望学习不同技术领域的小白或进阶学习者。可作为毕设项目、课程设计、大作业、工程实训或初期项目立项。 【附加价值】:项目具有较高的学习借鉴价值,也可直接拿来修改复刻。对于有一定基础或热衷于研究的人来说,可以在这些基础代码上进行修改和扩展,实现其他功能。 【沟通交流】:有任何使用上的问题,欢迎随时与博主沟通,博主会及时解答。鼓励下载和使用,并欢迎大家互相学习,共同进步。【项目资源
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值