20.ReenterLock重入锁
发布时间:2020-12-15 07:59:23 所属栏目:Java 来源:网络整理
导读:import java.util.concurrent.locks.ReentrantLock;/** * 重入锁 ReenterLock 一个线程允许连续获得同一把锁,注意:必须释放相同次数,释放次数多,会异常,少了相当于线程还持有这个锁,其他线程无法进入临界区 * 需要手动指定何时加锁何时释放锁 * Reente
import java.util.concurrent.locks.ReentrantLock; /** * 重入锁 ReenterLock 一个线程允许连续获得同一把锁,注意:必须释放相同次数,释放次数多,会异常,少了相当于线程还持有这个锁,其他线程无法进入临界区 * 需要手动指定何时加锁何时释放锁 * ReenterLock几个重要方法: - lock():获得锁,如果锁已经被占用,则等待 - lockInterruptibly():获得锁,但优先响应中断 - tryLock():尝试获得锁,成功返回true,失败返回false,该方法不等待,立即返回 - tryLock(long time,TimeUnit unit):在给定时间内尝试获得锁 - unlock():释放锁 */ public class ReentrantLockDemo implements Runnable{ public static Integer i = 0; public static ReentrantLock lock = new ReentrantLock(); @Override public void run() { for (int j = 0; j < 10000000; j++) { lock.lock(); try { i++; }finally { lock.unlock(); } } } public static void main(String[] args) throws InterruptedException{ ReentrantLockDemo r = new ReentrantLockDemo(); Thread thread1 = new Thread(r); Thread thread2 = new Thread(r); thread1.start();thread2.start(); thread1.join();thread2.join(); System.out.println(i);//20000000 } } 中断处理import java.util.concurrent.locks.ReentrantLock; /** * 避免死锁 * 重入锁的中断处理能力 */ public class IntLock implements Runnable{ public static ReentrantLock lock1 = new ReentrantLock(); public static ReentrantLock lock2 = new ReentrantLock(); int lock; public IntLock(int lock) { this.lock = lock; } @Override public void run() { try { if (lock==1){ lock1.lockInterruptibly(); Thread.sleep(500); lock2.lockInterruptibly();//可以对中断进行响应的锁 }else { lock2.lockInterruptibly(); Thread.sleep(500); lock1.lockInterruptibly(); //22行 } }catch (InterruptedException e){ e.printStackTrace(); }finally { //检查当前线程是否拥有该锁 if (lock1.isHeldByCurrentThread()) lock1.unlock(); if (lock2.isHeldByCurrentThread()) lock2.unlock(); System.out.println(Thread.currentThread().getId()+":线程退出"); } } public static void main(String[] args) throws InterruptedException{ IntLock i1 = new IntLock(1); IntLock i2 = new IntLock(2); Thread t1 = new Thread(i1); Thread t2 = new Thread(i2); t1.start(); t2.start(); Thread.sleep(1000); t2.interrupt(); //中断t2 ,t2放弃对lock1的申请,同时释放已获得的lock2 //java.lang.InterruptedException // at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireInterruptibly(AbstractQueuedSynchronizer.java:898) // at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireInterruptibly(AbstractQueuedSynchronizer.java:1222) // at java.util.concurrent.locks.ReentrantLock.lockInterruptibly(ReentrantLock.java:335) // at com.combat.IntLock.run(IntLock.java:22) // at java.lang.Thread.run(Thread.java:748) //10:线程退出 //9:线程退出 } } 限时等待import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; /** * 限时等待锁 */ public class TimeLockDemo implements Runnable{ public static ReentrantLock lock = new ReentrantLock(); @Override public void run() { try { if (lock.tryLock(5,TimeUnit.SECONDS)){ //等待时间,计时单位 Thread.sleep(6000); }else { System.out.println("get lock failed"); } } catch (InterruptedException e) { e.printStackTrace(); } finally { if (lock.isHeldByCurrentThread())lock.unlock(); } } public static void main(String[] args){ TimeLockDemo demo = new TimeLockDemo(); Thread t1 = new Thread(demo); Thread t2 = new Thread(demo); t1.start(); t2.start(); } //get lock failed //由于占用锁的线程为6秒,另一个线程无法在5秒的等待时间内获得锁,因此请求锁失败 } import java.util.concurrent.TimeUnit; import java.util.concurrent.locks.ReentrantLock; /** * tryLock * 限时等待锁 无参数 如果锁被其他线程占用,则当前线程不会进行等待,而是立即返回false,不会引起线程等待 */ public class TimeLockDemo2 implements Runnable{ public static ReentrantLock lock1 = new ReentrantLock(); public static ReentrantLock lock2 = new ReentrantLock(); int lock; public TimeLockDemo2(int lock) { this.lock = lock; } @Override public void run() { if (lock == 1){ while (true){ if (lock1.tryLock()){ try { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } if (lock2.tryLock()){ try { System.out.println(Thread.currentThread().getId()+":my job done"); return; } finally { lock2.unlock(); } } } finally { lock1.unlock(); } } } }else { while (true){ if (lock2.tryLock()){ try { try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } if (lock1.tryLock()){ try { System.out.println(Thread.currentThread().getId()+":my job done"); return; } finally { lock1.unlock(); } } } finally { lock2.unlock(); } } } } } public static void main(String[] args){ TimeLockDemo2 r1 = new TimeLockDemo2(1); TimeLockDemo2 r2 = new TimeLockDemo2(1); Thread t1 = new Thread(r1); Thread t2 = new Thread(r2); t1.start(); t2.start(); } //9:my job done //10:my job done } 公平锁import java.util.concurrent.locks.ReentrantLock; /** * 公平锁 * synchronized产生的锁是非公平锁 * 重入锁可以设置公平性 */ public class FairLock implements Runnable{ public static ReentrantLock lock = new ReentrantLock(true); @Override public void run() { while (true){ try { lock.lock(); System.out.println(Thread.currentThread().getName()+"获得锁"); } finally { lock.unlock(); } } } public static void main(String[] args) throws InterruptedException{ FairLock lock = new FairLock(); Thread t1 = new Thread(lock,"thread_t1"); Thread t2 = new Thread(lock,"thread_t2"); t1.start(); t2.start(); } //... //thread_t2获得锁 //thread_t1获得锁 //thread_t2获得锁 //thread_t1获得锁 //thread_t2获得锁 //... //两个线程基本交替获得锁 //而非公平锁,一个线程会倾向于再次获得已持有的锁,这种分配方式是高效的,但无公平性可言 } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |