精华内容
下载资源
问答
  • Java同步锁

    2019-05-16 21:07:57
    Java5开始,Java提供了一种功能更强大的线程同步机制——通过显式定义同步锁 对象来实现同步,在这种机制下,同步锁由Lock对象充当。 Lock提供了比synchronized方法和synchronized代码块更广泛的锁定操作,Lock...

    从Java5开始,Java提供了一种功能更强大的线程同步机制——通过显式定义同步锁 对象来实现同步,在这种机制下,同步锁由Lock对象充当。 Lock提供了比synchronized方法和synchronized代码块更广泛的锁定操作,Lock允许 实现更灵活的结构,可以具有差别很大的属性。 Lock是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占 访问,每次只能有一个线程对Lock对象加锁,线程开始访问共享资源之前应先获得 Lock对象。 在实现线程安全的控制中,比较常用的是 ReentrantLock(可重入锁)。使用该Lock 对象可以显式地加锁、释放锁。 ReentrantLock的代码格式如下:

    import java.util.concurrent.locks.ReentrantLock;

        class ClassName{

        //定义锁对象

        private final ReentrantLock lock=new ReentrantLock();

        //需要保证线程安全的方法

        public void methodName(){

        //加锁

        lock.lock();

        try{

           //代码块

    }

    //使用finally块来保证一定可以释放锁

    finally{

        //释放锁

        lock.unlock();

    }

    }

    展开全文
  • Java 同步锁

    2018-03-23 16:57:14
    synchronized是java中的一个关键字,在JVM层面上实现的,使用时不需要管理的获取和释放。(synchronized发生异常时,会自动释放线程占有的) 直接上代码: public class SynchronziedTest implements Runnable{ ...
    主要理清锁的使用和本质锁的是什么:
    	synchronized:
    synchronized是java中的一个关键字,在JVM层面上实现的,使用时不需要管理锁的获取和释放。(synchronized发生异常时,会自动释放线程占有的锁)
    直接上代码:
    public class SynchronziedTest implements Runnable{
        //非静态属性
        private int num;
        //非静态属性,加了volatile关键字(1.该值直接刷新到主存,2.禁止jvm指令重排)
        private volatile int count;
        静态属性
        private static int other;
        //静态属性
        private static int changme = 0;
        //静态属性,同时加上volatile关键字
        private static volatile int sum;
        //类的静态属性
        private static final Object obj = new Object();
        //据说,此锁更可提高性能。源于:锁的对象越小越好
        private static byte block[] = {};
        //方法上加同步,用的对象锁:锁住的是当前对象,不同对象操作时,线程不安全
        public synchronized void addNum(){
            num++;
        }
        //非静态方法中的代码块加同步
        public void addCount(){
            //锁住的是当前对象的类对象
            synchronized (this.getClass()){
                count+=2;
            }
        }
        //非静态方法中的代码块加同步,锁的是类的静态成员属性
        public void mulCount(){
            synchronized (SynchronziedTest.obj){
                count-=1;
            }
        }
        //非静态方法中的代码块加同步
        public void addOther(){
            //锁住的是当前对象的类对象
            synchronized (this.getClass()){
                other+=2;
            }
        }
        //非静态方法中的代码块加同步,锁的是类的静态成员属性(属性必须被static以及final修饰,否则报错)
        public void mulOther(){
            synchronized (SynchronziedTest.obj){
                other-=1;
            }
        }
        //静态方法加同步,对静态变量进行操作,锁的是当前类对象
        public synchronized static void addchangme(){
            changme+=5;
        }
        //静态方法中静态代码块加同步,对静态变量chanme进行操作
        public static void mulchangme(){
            //同步锁锁住的是该类的静态成员属性
            synchronized (SynchronziedTest.block){
                for (int i=0;i<2;i++){
                    changme-=1;
                }
            }
        }
        //非静态方法加同步,操作静态属性
        public synchronized void sum(){
            sum+=10;
        }
    
        //非静态方法
        public void mulSum(){
            //代码块上加同步,操作静态属性
            synchronized (SynchronziedTest.class){
                for (int i=0;i<3;i++){
                    sum-=1;
                }
            }
        }
        public void printer(){
            //计划值为2:实际值为1:,即同步没有生效
            System.out.println(Thread.currentThread().getName()+" num值为: " + num);
            //计划值为:实际值为1:,即同步没有生效
            System.out.println(Thread.currentThread().getName()+" count值为: " + count);
            //计划值为2:实际值为2:,即同步生效
            System.out.println(Thread.currentThread().getName()+" other值为: " + other);
            //计划值为6:实际值为6:,即同步生效
            System.out.println(Thread.currentThread().getName()+" changme值为: " + changme);
            //计划值为14:实际值为14:,即同步生效
            System.out.println(Thread.currentThread().getName()+" sum值为: " + sum);
        }
        @Override
        public void run() {
            addNum();
            addCount();
            mulCount();
            addOther();
            mulOther();
            addchangme();
            mulchangme();
            sum();
            mulSum();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            printer();
        }
    }
    
    public class Test {
        public static void main(String[] args) {
            Thread t1 = new Thread(new SynchronziedTest(),"线程1");
            Thread t2 = new Thread(new SynchronziedTest(),"线程2");
            t1.start();
            t2.start();
        }
    }
    
    运行结果:
    
    线程2 num值为: 1
    线程2 count值为: 1
    线程2 other值为: 2
    线程2 changme值为: 6
    线程2 sum值为: 14
    线程1 num值为: 1
    线程1 count值为: 1
    线程1 other值为: 2
    线程1 changme值为: 6
    线程1 sum值为: 14
    确保多线程操作的资源是同一资源两种方式:单列(确保同一对象)/static关键字(确保类的同一属性)
    	Lock:
    Lock是一个接口,通过代码实现,使用时候需要手动进行锁的释放,如果没有主动释放,很容易造成死锁(需要在finally块中释放锁)
    直接上代码:
    public class LockTest implements Runnable{
        //非静态属性
        private int num;
        //非静态属性
        private int A;
        //非静态属性
        private int B;
        //非静态属性,加了volatile关键字(1.该值直接刷新到主存,2.禁止jvm指令重排)
        private volatile int count;
        静态属性
        private static int other;
        //静态属性
        private static int changme = 0;
        //静态属性,同时加上volatile关键字
        private static volatile int sum;
        //非静态锁
        private Lock lock1 = new ReentrantLock();
        //静态锁
        private static Lock lock2 = new ReentrantLock();
        public void addNum(){
            Lock lock3 = new ReentrantLock();
            lock3.lock();
            try {
                for (int i = 0;i<5;i++){
                    num++;
                }
            }finally {
                lock3.unlock();
            }
        }
        public void mulNum(){
            Lock lock3 = new ReentrantLock();
            lock3.lock();
            try {
                num--;
            }finally {
                lock3.unlock();
            }
        }
        public void addCount(){
            lock1.lock();
            try {
                count+=2;
            }finally {
                lock1.unlock();
            }
        }
        public void mulCount(){
            lock1.lock();
            try {
                count-=1;
            }finally {
                lock1.unlock();
            }
        }
        public void addOther(){
            lock2.lock();
            try{
                other+=2;
            }finally {
                lock2.unlock();
            }
        }
          public void mulOther(){
            lock2.lock();
            try{
                other-=1;
            }finally {
                lock2.unlock();
            }
    
        }
        public static void addchangme(){
            lock2.lock();
            try{
                changme+=5;
            }finally {
                lock2.unlock();
            }
        }
        public static void mulchangme(){
    
            lock2.lock();
            try{
                for (int i=0;i<2;i++){
                    changme-=1;
                }
            }finally {
                lock2.unlock();
            }
        }
        public void sum(){
            lock2.lock();
            try{
                for (int i=0;i<2;i++){
                    sum+=10;
                }
            }finally {
                lock2.unlock();
            }
        }
        public void mulSum(){
            lock2.lock();
            try{
                for (int i=0;i<3;i++){
                    sum-=1;
                }
            }finally {
                lock2.unlock();
            }
        }
        public void addA(){
            lock2.lock();
            try {
                for (int i = 0;i<3;i++){
                    A++;
                }
            }finally {
                lock2.unlock();
            }
        }
        public void mulA(){
            lock2.lock();
            try {
                A--;
            }finally {
                lock2.unlock();
            }
        }
        public void addB(){
            lock1.lock();
            try {
                for (int i = 0;i<3;i++){
                    B++;
                }
            }finally {
                lock1.unlock();
            }
        }
        public void mulB(){
            lock1.lock();
            try {
                B--;
            }finally {
                lock1.unlock();
            }
        }
        //多线程操作成功同步条件:
        //1.使用的全局锁(Lock为类的静态成员属性);
        //2.对类的全局变量进行操作(类的静态成员属性);
        public void printer(){
            //计划值为8:实际值为4:,即同步没有生效
            System.out.println(Thread.currentThread().getName()+" num值为: " + num);
    
            //计划值为2:实际值为1:,即同步没有生效
            System.out.println(Thread.currentThread().getName()+" count值为: " + count);
            //计划值为2:实际值为2:,即同步生效
            System.out.println(Thread.currentThread().getName()+" other值为: " + other);
            //计划值为6:实际值为6:,即同步生效
            System.out.println(Thread.currentThread().getName()+" changme值为: " + changme);
            //计划值为34:实际值为34:,即同步生效
            System.out.println(Thread.currentThread().getName()+" sum值为: " + sum);
            //计划值为4:实际值为2:,即同步不生效
            System.out.println(Thread.currentThread().getName()+" A值为: " + A);
            //计划值为4:实际值为2:,即同步不生效
            System.out.println(Thread.currentThread().getName()+" B值为: " + B);
        }
        @Override
        public void run() {
            addNum();
            mulNum();
            addCount();
            mulCount();
            addOther();
            mulOther();
            addchangme();
            mulchangme();
            sum();
            mulSum();
            addA();
            mulA();
            addB();
            mulB();
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            printer();
        }
    }
    public class Test {
        public static void main(String[] args) {
            Thread t1 = new Thread(new LockTest(),"线程1");
    
            Thread t2 = new Thread(new LockTest(),"线程2");
            t1.start();
            t2.start();
        }
    
    }
    线程1 num值为: 4
    线程1 count值为: 1
    线程1 other值为: 2
    线程1 changme值为: 6
    线程1 sum值为: 34
    线程1 A值为: 2
    线程1 B值为: 2
    线程2 num值为: 4
    线程2 count值为: 1
    线程2 other值为: 2
    线程2 changme值为: 6
    线程2 sum值为: 34
    线程2 A值为: 2
    线程2 B值为: 2
    确保多线程操作的资源是同一资源两种方式:单列/static关键字
    	结论:
    使用同步锁,一定要搞清楚,需要使用类锁,还是对象锁;如果是不同对象多线程操作同一资源情况,要使用类锁;如果是同一个对象多线程操作同一资源时,需要使用对象锁。具体情况采用相应的锁进行同步问题。
    文章有误,欢迎指出!
    展开全文
  • 简介synchronized关键字是Java里面最基本的同步手段,它经过编译之后,会在同步块的前后分别生成 monitorenter和 monitorexit字节码指令,这两个字节码指令都需要一个引用类型的参数来指明要锁定和解锁的对象;...

    简介

    synchronized关键字是Java里面最基本的同步手段,它经过编译之后,会在同步块的前后分别生成 monitorenter和 monitorexit字节码指令,这两个字节码指令都需要一个引用类型的参数来指明要锁定和解锁的对象;而直接使用 synchronized 关键字锁定方法时,生成的字节码指令里面并没有 monitorenter 和 monitorexit 这两个指令,而是为方法添加了一个flags: ACC_SYNCHRONIZED, 该标识指明了该方法是一个同步方法。

    synchronized 的两种不同用法

    一、作用于方法上

    public synchronized void method1(){

    System.out.println(1);

    }

    查看编译后的字节码,发现会在方法的中加入ACC_SYNCHRONIZED的标识:

    public synchronized void method1();

    descriptor: ()V

    flags: (0x0021) ACC_PUBLIC, **ACC_SYNCHRONIZED**

    Code:

    stack=2, locals=1, args_size=1

    二、作用于代码块

    public void method3(){

    synchronized(this){

    System.out.println(3);

    }

    }

    查看编译后的字节码,发现会在同步块的前后分别生成 monitorenter和 monitorexit字节码指令

    public void method3();

    descriptor: ()V

    flags: (0x0001) ACC_PUBLIC

    Code:

    stack=2, locals=3, args_size=1

    0: aload_0

    1: dup

    2: astore_1

    3: **monitorenter**

    4: getstatic #2 // Field java/lang/System.out:Ljava/io/PrintStream;

    7: iconst_3

    8: invokevirtual #3 // Method java/io/PrintStream.println:(I)V

    11: aload_1

    12: **monitorexit**

    ... 省略...

    实现原理

    在学习Java内存模型内存间的交互操作的时候,知道JAVA内存模型还提供了更大范围的原子性保证 :lock和 unlock操作。

    但是lock和 unlock操作并 没有直接提供给用户使用,而是提供了更高层次的字节码指令 monitorenter和 monitorexit来隐式的使用lock和 unlock操作。

    Lock(锁定)命令:把一个变量标识为一条线程独占的状态,作用于主内存的变量

    unlock(解锁)命令:把处于锁定状态的变量释放锁,缩放锁后其他线程才可以锁定,作用于主内存的变量

    而 synchronized 就是使用 monitorenter 和 monitorexit 这两个指令来实现锁的功能的。

    根据JVM规范的要求,在执行monitorenter指令的时候,首先要去尝试获取对象的锁,如果这个对象没有被锁定,或者当前线程已经拥有了这个对象的锁,就把锁的计数器加1,相应地,在执行monitorexit的时候会把计数器减1,当计数器减小为0时,锁就释放了。所以 synchronized 对同一条线程来说是一个可重入的。

    synchronized 同步块在已进入的线程执行完成之前,会阻塞后面的线程进入,而JAVA的线程是映射到操作系统的原生线程之上的,如果要阻塞或唤醒一个线程,都需要操作系统来帮忙完成,这就需要从用户态切换到内核态中,状态转换需要消耗很多的处理器时间,对与简单的同步块,状态转换消耗的时候可能比用户代码执行的时间还要长,所以 synchronized 是JAVA 语言中一个重量级的操作。

    锁优化

    总结

    (1)synchronized在编译时会在同步块前后生成monitorenter和monitorexit字节码指令或者ACC_SYNCHRONIZED的标识;

    (2)monitorenter和monitorexit字节码指令需要一个引用类型的参数,基本类型不可以哦;

    (3)monitorenter和monitorexit字节码指令更底层是使用Java内存模型的lock和unlock指令;

    (4)synchronized是可重入锁;

    (5)synchronized是非公平锁;

    (6)synchronized可以同时保证原子性、可见性、有序性;

    (7)synchronized有三种状态:偏向锁、轻量级锁、重量级锁;

    展开全文
  • 主要介绍了Java 同步锁(synchronized)详解及实例的相关资料,需要的朋友可以参考下
  • 评论#re: java 同步锁(synchronized)2012-10-29 15:46eagledame兄弟 是不是搞错了啊a号窗口 ,售出20号车票a号窗口 ,售出19号车票a号窗口 ,售出18号车票a号窗口 ,售出17号车票a号窗口 ,售出16号车票a号窗口 ,...

    评论

    # re: java 同步锁(synchronized)

    2012-10-29 15:46

    eagledame

    兄弟 是不是搞错了啊

    a号窗口 ,售出20号车票

    a号窗口 ,售出19号车票

    a号窗口 ,售出18号车票

    a号窗口 ,售出17号车票

    a号窗口 ,售出16号车票

    a号窗口 ,售出15号车票

    a号窗口 ,售出14号车票

    a号窗口 ,售出13号车票

    a号窗口 ,售出12号车票

    a号窗口 ,售出11号车票

    d号窗口 ,售出10号车票

    d号窗口 ,售出9号车票

    d号窗口 ,售出8号车票

    d号窗口 ,售出7号车票

    d号窗口 ,售出6号车票

    d号窗口 ,售出5号车票

    d号窗口 ,售出4号车票  回复  更多评论

    # re: java 同步锁(synchronized)

    2012-10-29 15:56

    eagledame

    兄弟 我执行了你的程序1 和程序2 结果如上 。和你说的完全不一样 。求解释   回复  更多评论

    # re: java 同步锁(synchronized)

    2012-12-11 17:30

    游客

    卖完票 记得ticket--  回复  更多评论

    # re: java 同步锁(synchronized)

    2013-03-26 16:08

    马容亮

    我的理解 是java默认多线程,但是 多线程并发会导致 公用变量处理不准确,synchronized 同步 使 每个线程处理公用变量时,能够在一个完善的队列中完成。  回复  更多评论

    # re: java 同步锁(synchronized)

    2014-06-05 01:04

    @eagledame

    把值设置大点儿  回复  更多评论

    # re: java 同步锁(synchronized)

    2014-08-16 11:32

    文宇

    程序一和程序二都可以多窗口售票,只是票的总数不够大,没有等到b,c线程执行,当ticket=1000时,就可以看到  回复  更多评论

    # re: java 同步锁(synchronized)[未登录]

    2014-10-08 09:16

    秋风

    写得太好了,谢谢作者对人类软件事业进步所做出的重大贡献  回复  更多评论

    # re: java 同步锁(synchronized)

    2014-10-13 11:14

    zyongsh

    java线程调度是随机的,即使统一程序在同一台java虚拟机上执行的结果也可能会不同@eagledame

    回复  更多评论

    # re: java 同步锁(synchronized)

    2014-11-28 10:18

    家乐

    public void run()

    {

    while (true)

    {

    synchronized (this)

    {

    if (ticket > 0)

    {

    System.out.println(Thread.currentThread().getName() + "号窗口卖出" + this.ticket-- + "号票");

    }

    else

    {

    System.out.println(Thread.currentThread().getName() + "票已售完");

    break;

    }

    }

    try

    {

    Thread.sleep(1000);

    }

    catch (InterruptedException e)

    {

    e.printStackTrace();

    }

    }

    }  回复  更多评论

    # re: java 同步锁(synchronized)[未登录]

    2015-07-29 15:04

    111

    你这个不算是多线程的同步吧

    回复  更多评论

    # re: java 同步锁(synchronized)

    2015-07-29 18:40

    龙井

    2、使用同步块修改上面的例子修改错误的,正确如下:

    public void run()

    {

    for(int i=1;i<50;i++)

    {

    //休眠1s秒中,为了使效果更明显,否则可能出不了效果

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    synchronized(this){

    if(ticket>0)

    {

    System.out.println(Thread.currentThread().getName()+"号窗口卖出"+this.ticket--+"号票");

    }

    }

    }

    }  回复  更多评论

    展开全文
  • Java同步锁Lock的使用

    2017-05-31 14:25:40
    Java同步锁Lock的使用
  • java同步锁是一个互斥锁,只能有一个线程获取该锁,当线程A要获取B线程持有的对象锁的时候,只能在等待队列中等待,当B代码执行完毕释放锁,A才能获取该锁。如果B线程不释放锁,A线程会一直等待。 synchronzied和...
  • 这篇文章主要介绍了Java lock同步锁使用实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下1)Lock是一个接口,而synchronized是Java中的关键字,...
  • 下面小编就为大家带来一篇java同步锁的正确使用方法(必看篇)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
  • java 同步锁(synchronized)

    万次阅读 多人点赞 2013-10-12 15:30:43
    java 同步锁(synchronized)
  • 前言在开发当中我们常常会遇到多线程安全的问题,java中给我们提供了一个同步锁的关键字synchronized,它很好的解决多线程安全问题,本章节主要讲解synchronized用法和写法,避免和多同学在用不知道该如何书写,如有...
  • java中,同步锁和互斥锁英文关键字都是Synchronized,没有本质上的区别,两者都包括对资源的独占,使用起来没有区别。概念上的区别是1:互斥是通过竞争对资源的独占使用,彼此没有什么关系,执行顺序是一个乱序,...
  • Synchronized 同步锁工作原理(Fu++聚合支付收款云平台)1、在Java中, Synchronized 关键字是用来控制线程同步的,就是在多线程的环境下,控制 Synchronized 代码段不被多个线程同时执行。 Synchronized 既可以加在一...
  • 课程简介:课程目标:通过本课程的学习,理解并掌握Java多线程中的同步,提升自身技术能力与价值。适用人群:具有Java基础的人群,希望学习掌握Java多线程的人群。课程概述:线程同步是指多线程通过特定的设置...
  • 简述Java中每个对象都可以用来实现一个同步,这些被称为内置(Intrinsic Lock)或监视器(Monitor Lock)。具体表现形式如下:1、普通同步方法,的是当前实例对象2、静态同步方法,的是当前Class对象3、...
  • 接口 Lock实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。...一次只能有一个线程获得,对共享资源的所有访问都需要首先获得。不过,某些可能允许对共享资源并发访问,如ReadWriteLock 的...
  • 这篇文章主要介绍了Spring注解和同步锁不能同步问题解决,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下结论:如果在service层的方法上同时使用事务和同步锁...
  • java 同步锁(synchronized) 在java中,Synchronized就是一把锁,他可以锁定一个方法,也可以锁定一个方法,我擦,其实这两个东西就是一样的。块不就是一个没有名字的方法么,方法就是一个有名字的块。本文就用块来...
  • Java同步锁的实现

    2020-10-07 14:09:13
    Java的内置锁一直都是备受争议的。 在JDK1.6之前,synchronized这个重量级锁的性能一直都是较为低下;...实现自己的同步锁 【先来看看这个栗子】在一个不加锁的情况下,多个线程对同一个资源的操作(如下代码),我们.
  • Java同步锁全息详解

    2018-01-04 18:15:15
    1.为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块。其语法如下: synchronized(obj){ //同步代码块 } 其中obj就是同步监视...
  • 1. 什么是可重入(ReentrantLock)?答: java.util.concurrent.lock 中的 Lock 框架是锁定的一个抽象,它允许把锁定的实现作为 Java 类,而不是作为语言的特性来实现。这就为 Lock 的多种实现留下了空间,各种实现...
  • 同步,学习多线程避不开的两个问题,Java提供了synchronized关键字来同步方法和代码块,还提供了很多方便易用的并发工具类,例如:LockSupport、CyclicBarrier、CountDownLatch、Semaphore…有没有想过自己实现...
  • java同步锁的实现

    2020-11-23 10:44:50
    那么java项目中为了保证一个方法或属性在高并发情况下的同一时间只能被同一个线程执行,在传统单体应用单机部署的情况下,可以使用Java并发处理相关的API(如ReentrantLock或Synchronized)进行互斥控制。 下面主要...
  • java同步锁问题!

    2020-11-08 21:28:05
    class Station extends Thread{ public Station(String name) { super(name); } ... boolean flag=true;... private Object lock=new Object();... System.out.println(Station.currentThread().getName() + ...
  • 同步锁分类对象锁(this)类锁(类的字节码文件对象即类名.class)字符串锁(比较特别)应用场景在多线程下对共享资源的安全操作。需求:启动5个线程对共享资源total进行安全操作。同步锁在多线程单例模式下的使用以上三类...
  • js模拟java同步锁

    千次阅读 2018-03-15 11:12:00
     * js实现同步锁,缺省锁定10秒  * 示例  * if(jsynchronized("handIn")){  ...  * }  */ var locks = []; var LOCKTIME_DEFAULT = 1000 * 10; function jsynchronized(lockName,lock...
  • 方法 对象 class 变量

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 21,660
精华内容 8,664
关键字:

java同步锁

java 订阅