精华内容
下载资源
问答
  • Java加锁工具类

    2019-05-24 09:06:15
    Java加锁工具类。用于普通加锁。 可以用到的场景有: 1、多线程对同一数据进行处理时,通过此类进行简单加锁。 2、想保证后台同时,只有一个线程在处理某事情时。 3、更新数据库信息时。
  • java加锁方式

    千次阅读 2021-06-14 17:54:25
    java加锁方式 1、synchronized方式(重量级锁) 加锁方式:synchronized(object)传入对象,不同对象代表不同锁,可以在线程外部新建对象。 public class SellCinemaTicketThread implements Runnable { static ...

    java加锁方式

    1、synchronized方式(重量级锁)

    加锁方式:synchronized(object)传入对象,不同对象代表不同锁,可以在线程外部新建对象。

    public class SellCinemaTicketThread implements Runnable {
        static int num = 100;
        Object object = new Object();
    
        @Override
        public void run() {
            while (true) {
                synchronized (object) {
                    if (num > 0) {
                        System.out.println(Thread.currentThread().getName() + "买票啦---" + num);
                        num--;
                    }
                }
    
            }
        }
    }
    

    也可以作为方法的修饰传入

    public class SellCinemaTicketThread1 implements Runnable {
        static int num = 100;
    
        @Override
        public void run() {
            sell();
        }
    
        private synchronized void sell() {
            while (true) {
                if (num > 0) {
                    System.out.println(Thread.currentThread().getName() + "买票啦---" + num);
                    num--;
                }
            }
        }
    }
    

    2、Lock(比synchronized要轻量级)

    • 新建锁对象Lock l = new ReentrantLock();
    • 加锁 l.lock()
    • 解锁 l.unlock()
    public class TestLockSellTicket implements Runnable {
        static int num = 100;
        Lock l = new ReentrantLock();
    
        @Override
        public void run() {
            while (true) {
                l.lock();
                if (num > 0) {
                    try {
                        Thread.sleep(100);
                        System.out.println("买票啦---" + num);
                        num--;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } finally {
                        l.unlock();
                    }
    
                }
    
            }
    
        }
    }
    

    3、wait() notify() notifyAll()

    /*
    wait() notify() notifyAll() 是Object上的方法,只有Object是对象监视器时候才能调用此方法
        notify() 唤醒同一个对象监视器上的线程
    
        wait(Long timeout) 传入数值,表示超过某个时间还没有被唤醒则自动唤醒
    
        wait和sleep区别:
            sleep() 可以在同步中和同步外使用,线程遇到sleep不释放锁,时间到了继续向下执行
            wait() 只能在同步中使用,由对象监视器调用, 线程进入wait状态时释放掉锁
    
    */
    
    public class TestWaitAndNotify {
        public static void main(String[] args) {
            Object obj = new Object();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (obj) {
                        System.out.println("开始等待。。。。");
                        try {
                            obj.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println("等待结束。。。。");
                    }
                }
            }).start();
    
            new Thread(new Runnable() {
                @Override
                public void run() {
                    synchronized (obj) {
                        // 休眠两秒再唤醒线程
                        try {
                            Thread.sleep(2000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        obj.notify();
                    }
                }
            }).start();
        }
    }
    
    

    买票加锁

    SellCinemaTicketThread1类

    
    public class SellCinemaTicketThread1 implements Runnable {
        static int num = 100;
    
        @Override
        public void run() {
            sell();
        }
    
        private synchronized void sell() {
            while (true) {
                if (num > 0) {
                    System.out.println(Thread.currentThread().getName() + "买票啦---" + num);
                    num--;
                }
            }
        }
    }
    

    TestSellCinemaTicket 买票类 多个线程同时卖票

    /*
    
    保持同步:
        代码块加锁  synchronized (任意对象即对象锁) {需要同步的对象}
        方法加锁 在方法返回值前加synchronized
            private synchronized void sell() {同步代码}
    */
    
    public class TestSellCinemaTicket {
        public static void main(String[] args) {
    //        Runnable r = new SellCinemaTicketThread();
            Runnable r = new SellCinemaTicketThread1();
    
            Thread t1 = new Thread(r);
            Thread t2 = new Thread(r);
            Thread t3 = new Thread(r);
    
            t1.start();
            t2.start();
            t3.start();
    
        }
    }
    
    
    展开全文
  • JAVA Lock加锁实例

    2018-07-10 16:11:17
    Lock锁是对象锁,仅在同一对象中,锁才会生效。...lock.tryLock()的加锁方式,不会堵塞,会立即返回加锁成功与否。(方案AEX) lock.tryLock(1000, TimeUnit.SECONDS)的加锁方式,允许堵塞时间,若在堵……
  • Java加锁机制

    2016-08-19 21:04:12
    “重入”意味着获取锁的操作的粒度是“线程”,而不是“调用”,这与pthread(POSIX线程)互斥体的默认加锁行为不同,pthread互斥体的获取操作是以“调用”为粒度的。 重入的一种实现方法:  为每个锁关联一...

    下列代码不是线程安全的,该Servlet在没有足够原子性保证的情况下对其最近计算结果进行缓存(不要这样做)

    @NotThreadSafe
    public class UnsafeCachingFactorizer implements Servlet{
    	private final AtomicReference<BigInteger> lastNumber = new AtomicReference<BigInteger>();
    	private final AtomicReference<BigInteger[]> lastFactors = new AtomicReference<BigInteger[]>();
    
    	@Override
    	public void init(ServletConfig config) throws ServletException {
    	}
    
    	@Override
    	public ServletConfig getServletConfig() {
    		return null;
    	}
    
    	@Override
    	public void service(ServletRequest req, ServletResponse res)
    			throws ServletException, IOException {
    		BigInteger i = extractFromRequest(req);
    		if(i.equals(lastNumber.get())){
    			encodeIntoResponse(res,lastNumber.get());
    		}else{
    			BigInteger[] factors = factor(i);
    			lastNumber.set(i);
    			lastFactors.set(factors);
    			encodeIntoResponse(res,factors);
    		}
    	}
    
    	@Override
    	public String getServletInfo() {
    		return null;
    	}
    
    	@Override
    	public void destroy() {
    	}
    
    }
    
    在UnsafeCachingFactorizer中存在竞态条件,可能产出错误结果。
    UnsafeCachingFactorizer的不变性条件之一是:在lastFactors中缓存的因数之积应该等于在lastNumber中缓存的数值。只有确保了这个不变性条件不被破坏,上面的servlet才是正确的。

    要保持状态的一致性,就需要在单个原子操作中更新所有相关的状态变量。

    1.内置锁

        每个Java对象都可以用做一个实现同步的锁,这些锁被称为内置锁(Intrinsic Lock)或监视器锁(Monitor Lock)。获得内置锁的唯一途径就是进入由这个锁保护的同步代码块或方法。Java的内置锁相当于一种互斥体(或互斥锁),这意味着最多只有一个线程能持有这种锁。

    同步代码块(Synchronized Block)包括两部分:

      1.作为锁的对象引用

      2.作为由这个锁保护的代码块

    静态的synchronized方法以Class对象作为锁

    synchronized(lock){

    //访问或修改由锁保护的共享状态

    }

    任何一个执行同步代码块的线程,都不可能看到有其它线程正在执行由同一个锁保护的同步代码块。

    下面的代码是线程安全的,这个Servlet能正确地缓存最新的计算结果,但并发性却非常糟糕(不要这么做)

    @ThreadSafe
    public class SynchronizedFactorizer implements Servlet{
    
    	<span style="color:#ff0000;">@GuardedBy("this")</span> private BigInteger lastNumber;
    	<span style="color:#ff0000;">@GuardedBy("this")</span> private BigInteger[] lastFactors;
    	
    	@Override
    	public void init(ServletConfig config) throws ServletException {
    	}
    
    	@Override
    	public ServletConfig getServletConfig() {
    		return null;
    	}
    
    	@Override
    	public <span style="color:#ff0000;">synchronized</span> void service(ServletRequest req, ServletResponse res)
    			throws ServletException, IOException {
    		BigInteger i = extractFromRequest(req);
    		if(i.equals(lastNumber)){
    			encodeIntoResponse(res,lastFactors);
    		}else{
    			BigInteger[] factors = factor(i);
    			lastNumber = i;
    			lastFactors = factors;
    			encodeIntoResponse(res,factors);
    		}
    	}
    
    	@Override
    	public String getServletInfo() {
    		return null;
    	}
    
    	@Override
    	public void destroy() {
    	}
    
    }
    


    2.重入

    内置锁是可重入的,因此如果某个线程试图获得一个已经由它自己持有的锁,那么这个请求就会成功。

    “重入”意味着获取锁的操作的粒度是“线程”,而不是“调用”,这与pthread(POSIX线程)互斥体的默认加锁行为不同,pthread互斥体的获取操作是以“调用”为粒度的。

    重入的一种实现方法:

        为每个锁关联一个获取计数值和一个所有者线程。

    当计数值为0时,这个锁就被认为是没有被任何线程持有。当线程请求一个未被持有的锁时,JVM将记下锁的持有者,并且将获取计数值置为1。如果同一个线程再次获取这个锁,计数值将递增,而当线程退出同步代码块时,计数器会相应递减。当计数值为0时,这个锁将被释放。 

    如果内置锁不是可重入的,那么这段代码将发生死锁。

    public class Widget {
    
    	public <span style="color:#ff0000;">synchronized</span> void doSomething(){
    		//doSomething
    	}
    }

    public class LoggingWidget <span style="color:#ff0000;">extends Widget</span>{
            @Override  <span style="white-space:pre">	</span>
    	public <span style="color:#ff0000;">synchronized</span> void doSomething(){
    		System.out.println(toString()+":calling doSomething");
    		super.doSomething();
    	}
    }
    

    由于Widget和LoggingWidget中doSomething方法都是Synchronized方法,因此每个doSomething方法在执行前都会获取Widget上的锁。然而,如果内置锁不是可重入的,那么在调用super.doSomething时将无法获得Widget上的锁,因为这个锁已经被持有,从而线程将永远停顿下去,等待一个永远也无法获得的锁。重入则避免了这种死锁情况的发生。



    展开全文
  • java加锁的意义

    千次阅读 2017-07-27 15:15:12
    java加锁:synchronized、 1. 互斥: 2. 内存可见: 加锁的含义不仅仅局限于互斥行为,还包括内存可见性。为了确保所有线程都能看到共享变量的最新值,所有执行读操作或者写操作的线程都必须在同一个锁上同步。 ...

    java加锁:synchronized、

    1. 互斥:


    2. 内存可见:

    加锁的含义不仅仅局限于互斥行为,还包括内存可见性。为了确保所有线程都能看到共享变量的最新值,所有执行读操作或者写操作的线程都必须在同一个锁上同步。



    详见:《java并发编程实战》3.1.3

    展开全文
  • java加锁方法

    千次阅读 2019-07-16 14:33:47
    最直接也是最简单的方法,使用synchronized同步关键字: 使用Lock: ReenTrantLock lock = newReenTrantLock(); private void fun(){ lock.lock(); try{ 执行语句...... ........... ... lo...

    最直接也是最简单的方法,使用synchronized同步关键字:

     

    使用Lock:

    ReenTrantLock lock = new ReenTrantLock();

     

    private void fun(){

        lock.lock();

        try{

            执行语句......

            ...........

    } finally{

        lock.unlock();

    }

    }

    展开全文
  • java 多线程加锁

    2020-06-09 16:03:32
    java 加锁方法: 1:直接加 synchronized 关键字 2:使用lock private java.util.concurrent.locks.Lock lock = new ReentrantLock(); private void fun(){ lock.lock(); try{ 执行语句...... } ...
  • Java线程加锁的三种方式

    千次阅读 2018-12-03 15:00:11
    1.对象锁(同步块)——锁某一个对象 对象锁:顾名思义给对象上锁 当A线程访问一个object的时候,首先会获取该对象的对象锁,然后访问锁定的代码,而B线程访问一个对象object多顶的代码区时,因为线程A之前获取到...
  • java中Lock加锁操作

    2020-09-22 22:58:46
    加锁后必须解锁 Lock lock=new ReentrantLock(); lock.lock(); try { //do something } catch (Exception e) { //回滚try中的操作或者改成合适的状态值 e.printStackTrace(); }finally { lock.unlock(); ...
  • Java加锁Util类

    2018-12-21 17:55:00
    早期写了一个加锁的工具类,后面很多并发的时候,经常有用到,放到博客里方便用的时候获取 import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.ConcurrentHashMap; ...
  • 主要介绍了Java基于注解实现的锁实例解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • public class TestThread5 { static class Counter2 { public int count = 0; public int count2 = 0; //synchronized 关键字进行加锁操作 ... //进入increase方法会尝试加锁 方法执行完毕会解锁
  • java加锁和解锁

    千次阅读 2017-12-15 16:33:52
    1.java使用lock和synchronize进行锁处理效果是差不多的,但是lock需要手动去解锁,并且可以在方法内部任何地方添加,并且一定要在finally中解锁,但是 synchronize可以自动解锁代码, 并且只能加在方法、代码块上...
  • Java 多线程加锁的方式

    万次阅读 2018-07-20 09:42:47
    一.Java多线程可以通过: 1. synchronized关键字 2. Java.util.concurrent包中的lock接口和ReentrantLock实现类 这两种方式实现加锁。   二.synchronized关键字加锁的缺陷:   如果一个代码块被synchro...
  • JAVA如何在线程中加锁(四种方法)

    千次阅读 2020-04-22 11:12:00
    JAVA多线程锁 线程的生命周期 ​ 总共六种状态,可归结为五种,线程的最终是死亡,阻塞不是最终状态,只是一个临时状态。只有调用了start方法,线程才进入就绪阶段。 //新生 ​ NEW, //运行​ RUNNABLE, //阻塞​ ...
  • 主要介绍了Java Synchronized锁失败案例及解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • 1 加锁和释放锁的原理 现象 获取和释放锁的时机:内置锁 等价代码 深入JVM看字节码:反编译、monitor指令 package com.tzb.test.demo; import java.util.concurrent.locks.Lock; import java.util.concurrent....
  • //获得锁 RLock locker = RedisUtil.getClient().getLock("锁的名字,例:Locker:TestLockA"); //上锁 locker.lock(); try { /* 你自己看的业务代码 此处省略成千上万个BUG,祝君好运!... if (locker.isLock
  • 今天小编就为大家分享一篇关于Java双重检查加锁单例模式的详解,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
  • Java 多线程加锁的方式总结及对比

    万次阅读 多人点赞 2017-03-28 14:27:53
    一.Java多线程可以通过: 1. synchronized关键字 2. Java.util.concurrent包中的lock接口和ReentrantLock实现类 这两种方式实现加锁。 二.synchronized关键字加锁的缺陷: 如果一个代码块被s
  • 前言    在保证线程安全的机制 同步阻塞 中,加锁方式除了synchronized还有一个不同于它的,需要手动加锁解锁的方式:ReentrantLock类的实现。 一、Lock ...
  • 现有一业务api,需要对同时 进行该业务操作的(调用该api)进行限制,规则如下: 调用该业务 共有 N 中类型(不是参数),调用者属性 ...基于java 实现,不能再执行过程中开启线程分类别执行,加锁
  • java中同步加锁的几种方式

    千次阅读 2013-12-17 14:11:10
    同步加锁的几种方式: 1、使用静态代码块 static { list = Collections.synchronizedList(list); } 2、对方法进行加锁 public synchronized void add() {} 3、 Integer y = 5;//OK使用一个定值 synchronized...
  • Java中每个对象都有一个内置锁。 当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。获得一个对象的锁也称为获取锁、锁定对象、在对象上锁定或在对象上同步...
  • 主要介绍了java synchronized加载加锁-线程可重入详解及实例代码的相关资料,需要的朋友可以参考下
  • SynchronizedJava中每个对象都有一个内置锁,当程序运行到非静态的synchronized同步方法上时,自动获得与正在执行代码类的当前实例(this实例)有关的锁。获得一个对象的锁也称为获取锁、锁定对象、在对象上锁定或在...
  • Collections.synchronizedList(容器) 传入一个无锁的容器 返回一个加锁的容器
  • java方式: publicstatic synchronized int generate(StringtableName){  Stringsql = "select value from t_table_id where table_name=?";  Connectionconn = null;  PreparedStatementpstmt = ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 174,467
精华内容 69,786
关键字:

java加锁

java 订阅