Java的高并发编程系列(五)reentrantlock替换synchronized
2018-03-29 14:43
821 查看
java高并发编程主要有下面三个组成:
1.同步器synchronized
2.同步容器
3.线程池:threadPool、executort
本例中由于test1锁定this,只有test1执行完毕的时候,test2才能执行:
使用reentrantlock可以完成同样的功能, 需要注意的是,必须要必须要必须要手动释放锁(重要的事情说三遍)。使用syn锁定的话如果遇到异常,jvm会自动释放锁,但是lock必须手动释放锁,因此经常在finally中进行锁的释放。
使用reentrantlock可以进行“尝试锁定”tryLock,这样无法锁定,或者在指定时间内无法锁定,线程可以决定是否继续等待。
使用ReentrantLock还可以调用lockInterruptibly方法,可以对线程interrupt方法做出响应,在一个线程等待锁的过程中,可以被打断。
ReentrantLock还可以指定为公平锁
1.同步器synchronized
2.同步容器
3.线程池:threadPool、executort
本例中由于test1锁定this,只有test1执行完毕的时候,test2才能执行:
public class ReentrantLock1 { public synchronized void test1(){ for (int i = 0; i < 10; i++) { System.out.println(i); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } } public synchronized void test2(){ System.out.println("execute test2........"); } public static void main(String[] args) { ReentrantLock1 rl = new ReentrantLock1(); new Thread(rl::test1).start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(rl::test2).start(); } }
使用reentrantlock可以完成同样的功能, 需要注意的是,必须要必须要必须要手动释放锁(重要的事情说三遍)。使用syn锁定的话如果遇到异常,jvm会自动释放锁,但是lock必须手动释放锁,因此经常在finally中进行锁的释放。
public class ReentrantLock2 { Lock lock = new ReentrantLock(); public void test1(){ try { lock.lock(); //synchronized(this) for (int i = 0; i < 10; i++) { System.out.println(i); TimeUnit.SECONDS.sleep(1); } } catch (InterruptedException e) { e.printStackTrace(); } finally { //必须手动释放 lock.unlock(); } } public void test2(){ lock.lock(); System.out.println("execute test2........"); lock.unlock(); } public static void main(String[] args) { ReentrantLock2 rl = new ReentrantLock2(); new Thread(rl::test1).start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(rl::test2).start(); } }
使用reentrantlock可以进行“尝试锁定”tryLock,这样无法锁定,或者在指定时间内无法锁定,线程可以决定是否继续等待。
public class ReentrantLock3 { Lock lock = new ReentrantLock(); public void test1(){ try { lock.lock(); //synchronized(this) for (int i = 0; i < 10; i++) { System.out.println(i); TimeUnit.SECONDS.sleep(1); } } catch (InterruptedException e) { e.printStackTrace(); } finally { //必须手动释放 lock.unlock(); } } /** * 可以使用tryLock进行尝试锁定,不管锁定与否,方法都将继续执行 * 可以根据tryLock的返回值来判定是否锁定 * 也可以指定tryLock的时间,由于tryLock(time)抛出异常,所以要注意unclock的处理,必须放到finally中 */ public void test2(){ boolean locked = false; try { lock.tryLock(6, TimeUnit.SECONDS); System.out.println("test2...." + locked); } catch (InterruptedException e) { e.printStackTrace(); } finally { if (locked) { lock.unlock(); } } } public static void main(String[] args) { ReentrantLock3 rl = new ReentrantLock3(); new Thread(rl::test1).start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(rl::test2).start(); } }
使用ReentrantLock还可以调用lockInterruptibly方法,可以对线程interrupt方法做出响应,在一个线程等待锁的过程中,可以被打断。
public class ReentrantLock4 { public static void main(String[] args) { ReentrantLock lock = new ReentrantLock(); Thread t1 = new Thread(()->{ try { lock.lock(); System.out.println("t1 start"); TimeUnit.SECONDS.sleep(Integer.MAX_VALUE); System.out.println("t1 end"); } catch (InterruptedException e) { 4000 System.out.println("interrupted!"); } finally { lock.unlock(); } }); t1.start(); Thread t2 = new Thread(()->{ try { //lock.lock(); lock.lockInterruptibly(); //可以对interrupt()方法做出响应 System.out.println("t2 start"); TimeUnit.SECONDS.sleep(5); System.out.println("t2 end"); } catch (InterruptedException e) { System.out.println("interrupted!"); } finally { lock.unlock(); } }); t2.start(); try { TimeUnit.SECONDS.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } t2.interrupt(); //打断线程2的等待 } }
ReentrantLock还可以指定为公平锁
public class ReentrantLock5 extends Thread{ private static ReentrantLock lock = new ReentrantLock(true); //参数为true表示为公平锁,请对比输出结果 @Override public void run() { for (int i = 0; i < 100 ; i++) { lock.lock(); try { System.out.println(Thread.currentThread().getName() + "获得锁"); } catch (Exception e) { e.printStackTrace(); } finally { lock.unlock(); } } } public static void main(String[] args) { ReentrantLock5 rl = new ReentrantLock5(); Thread t1 = new Thread(rl); Thread t2 = new Thread(rl); t1.start(); t2.start(); } }
相关文章推荐
- Java 并发编程中使用 ReentrantLock 替代 synchronized 关键字原语
- Java 并发编程中使用 ReentrantLock 替代 synchronized 关键字原语
- 高级java必会系列二:多线程经常使用的3个关键字:synchronized、ReentrantLock、volatile
- Java 并发编程中使用 ReentrantLock 替代 synchronized 关键字原语
- Java 多线程(四)——线程同步(synchronized、ReentrantLock)
- Java中ReentrantLock和synchronized两种锁机制比较
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- JAVA可重入锁ReentrantLock和synchronized关键字
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- Java中的ReentrantLock和synchronized两种锁定机制的对比
- java的两种同步方式, Synchronized与ReentrantLock的区别
- Java中的ReentrantLock和synchronized两种锁机制的对比
- Java中Synchronized与ReentrantLock的不同以及ReentrantLock的使用
- Java 并发编程之ReentrantLock和synchronized锁
- Java中的ReentrantLock和synchronized两种锁定机制的对比