Java多线程编程之Lock用法实例

锁是控制多个线程对共享资源进行访问的工具。通常,锁提供了对共享资源的独占访问。一次只能有一个线程获得锁,对共享资源的所有访问都需要首先获得锁。不过,某些锁可能允许对共享资源并发访问,如 ReadWriteLock(维护了一对相关的锁,一个用于只读操作,另一个用于写入操作) 的读写锁。

1、Lock提供了无条件的、可轮询的、定时的、可中断的锁获取操作,所有加锁和解锁的方法都是显式的。

public interface Lock{
  void lock(); //加锁
  //优先考虑响应中断,而不是响应锁定的普通获取或重入获取
  void lockInterruptibly() throws InterruptedException;
  boolean tryLock(); //可定时和可轮询的锁获取模式
  boolean tryLock(long timeout,TimeUnit unit) throws InterruptedException;
  void unlock(); //解锁
  Condition newCondition();
}

2、ReentrantLock实现了lock接口,跟synchronized相比,ReentrantLock为处理不可用的锁提供了更多灵活性。
3、使用lock接口的规范形式要求在finally块中释放锁lock.unlock()。如果锁守护的代码在try块之外抛出了异常,它将永远不会被释放。

以下模拟Lock用法:假设有两个线程(A线程、B线程)去调用print(String name)方法,A线程负责打印'zhangsan'字符串,B线程负责打印'lisi'字符串。
1、当没有为print(String name)方法加上锁时,则会产生A线程还没有执行完毕,B线程已开始执行,那么打印出来的name就会出现如下问题。

2、当为print(String name)方法加上锁时,则会产生A执行完毕后,B线程才执行print(String name)方法,达到互斥或者说同步效果。

package com.ljq.test.thread;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

/**
 * 用Lock替代synchronized
 *
 * @author Administrator
 *
 */
public class LockTest {

  public static void main(String[] args) {
    new LockTest().init();
  }

  private void init() {
    final Outputer outputer = new Outputer();
    //A线程
    new Thread(new Runnable() {
      @Override
      public void run() {
        while (true) {
          try {
            Thread.sleep(10);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          outputer.output("zhangsan");
        }

      }
    }).start();

    //B线程
    new Thread(new Runnable() {
      @Override
      public void run() {
        while (true) {
          try {
            Thread.sleep(10);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
          outputer.output("lisi");
        }

      }
    }).start();

  }

  static class Outputer {
    Lock lock = new ReentrantLock();

    /**
     * 打印字符
     *
     * @param name
     */
    public void output(String name) {
      int len = name.length();
      lock.lock();
      try {
        for (int i = 0; i < len; i++) {
          System.out.print(name.charAt(i));
        }
        System.out.println();
      } finally {
        lock.unlock();
      }
    }
  }
}
(0)

相关推荐

  • java集合框架 arrayblockingqueue应用分析

    Queue ------------ 1.ArrayDeque, (数组双端队列) 2.PriorityQueue, (优先级队列) 3.ConcurrentLinkedQueue, (基于链表的并发队列) 4.DelayQueue, (延期阻塞队列)(阻塞队列实现了BlockingQueue接口) 5.ArrayBlockingQueue, (基于数组的并发阻塞队列) 6.LinkedBlockingQueue, (基于链表的FIFO阻塞队列) 7.LinkedBlockingDeque, (

  • java中LinkedBlockingQueue与ArrayBlockingQueue的异同

    相同: 1.LinkedBlockingQueue和ArrayBlockingQueue都实现了BlockingQueue接口: 2.LinkedBlockingQueue和ArrayBlockingQueue都是可阻塞的队列 内部都是使用ReentrantLock和Condition来保证生产和消费的同步: 当队列为空,消费者线程被阻塞:当队列装满,生产者线程被阻塞: 使用Condition的方法来同步和通信:await()和signal() 不同: 1.由上图可以看出,他们的锁机制不同 Li

  • 基于java中BlockingQueue的使用介绍

    最近在维护一个java工程,在群里面也就聊起来java的优劣!无奈一些Java的终极粉丝,总是号称性能已经不必C++差,并且很多标准类库都是大师级的人写的,如何如何稳定等等.索性就认真研究一番,他们给我的一项说明就是,在线程之间投递消息,用java已经封装好的BlockingQueue,就足够用了. 既然足够用那就写代码测试喽,简简单单写一个小程序做了一番测试: 复制代码 代码如下: //默认包 import java.util.concurrent.*; import base.MyRunna

  • 详解Java多线程编程中LockSupport类的线程阻塞用法

    LockSupport是用来创建锁和其他同步类的基本线程阻塞原语. LockSupport中的park() 和 unpark() 的作用分别是阻塞线程和解除阻塞线程,而且park()和unpark()不会遇到"Thread.suspend 和 Thread.resume所可能引发的死锁"问题. 因为park() 和 unpark()有许可的存在:调用 park() 的线程和另一个试图将其 unpark() 的线程之间的竞争将保持活性. 基本用法 LockSupport 很类似于二元信号

  • java Lock接口详解及实例代码

    java  Lock接口 java.util.concurrent.locks 接口Lock public interface Loce Loce实现提供了比使用synchronized方法和语句可获得的更广泛的锁定操作 import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; public class IntegerDemo { public static void main

  • java线程并发blockingqueue类使用示例

    如果BlockingQueue是满的任何试图往里存东西的操作也会被阻断进入等待状态,直到BlockingQueue里有新的空间才会被唤醒继续操作. BlockingQueue提供的方法主要有: add(anObject): 把anObject加到BlockingQueue里,如果BlockingQueue可以容纳返回true,否则抛出IllegalStateException异常. offer(anObject):把anObject加到BlockingQueue里,如果BlockingQueue

  • 详解Java多线程编程中互斥锁ReentrantLock类的用法

    0.关于互斥锁 所谓互斥锁, 指的是一次最多只能有一个线程持有的锁. 在jdk1.5之前, 我们通常使用synchronized机制控制多个线程对共享资源的访问. 而现在, Lock提供了比synchronized机制更广泛的锁定操作, Lock和synchronized机制的主要区别: synchronized机制提供了对与每个对象相关的隐式监视器锁的访问, 并强制所有锁获取和释放均要出现在一个块结构中, 当获取了多个锁时, 它们必须以相反的顺序释放. synchronized机制对锁的释放是

  • java线程阻塞中断与LockSupport使用介绍

    上周五和周末,工作忙里偷闲,在看java cocurrent中也顺便再温故了一下Thread.interrupt和java 5之后的LockSupport的实现. 在介绍之前,先抛几个问题. Thread.interrupt()方法和InterruptedException异常的关系?是由interrupt触发产生了InterruptedException异常? Thread.interrupt()会中断线程什么状态的工作? RUNNING or BLOCKING? 一般Thread编程需要关注

  • 深入Synchronized和java.util.concurrent.locks.Lock的区别详解

    主要相同点:Lock能完成Synchronized所实现的所有功能.主要不同点:Lock有比Synchronized更精确的线程予以和更好的性能.Synchronized会自动释放锁,但是Lock一定要求程序员手工释放,并且必须在finally从句中释放.synchronized 修饰方法时 表示同一个对象在不同的线程中 表现为同步队列如果实例化不同的对象 那么synchronized就不会出现同步效果了.1.对象的锁 所有对象都自动含有单一的锁. JVM负责跟踪对象被加锁的次数.如果一个对象被

  • java多线程并发中使用Lockers类将多线程共享资源锁定

    复制代码 代码如下: package com.yao; import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReadWriteLock;import java.util.c

  • Java多线程编程之读写锁ReadWriteLock用法实例

    读写锁:分为读锁和写锁,多个读锁不互斥,读锁与写锁互斥,这是由jvm自己控制的,你只要上好相应的锁即可.如果你的代码只读数据,可以很多人同时读,但不能同时写,那就上读锁:如果你的代码修改数据,只能有一个人在写,且不能同时读取,那就上写锁.总之,读的时候上读锁,写的时候上写锁! 三个线程读数据,三个线程写数据示例: 可以同时读,读的时候不能写,不能同时写,写的时候不能读. 读的时候上读锁,读完解锁:写的时候上写锁,写完解锁. 注意finally解锁. package com.ljq.test.th

  • SVN出现提示org.apache.subversion.javahl.ClientException: Attempted to lock an already-locked dir解决方案

    SVN出现提示org.apache.subversion.javahl.ClientException: Attempted to lock an already-locked dir解决方案 第一种方法: 通过svn插件来清理,首先选中项目,右键,选择team->refresh/cleanup即可.然后再更新文件就不会提示org.apache.subversion.javahl.ClientException: Attempted to lock an already-lockeddir了.但

  • Java并发编程之显示锁ReentrantLock和ReadWriteLock读写锁

    在Java5.0之前,只有synchronized(内置锁)和volatile. Java5.0后引入了显示锁ReentrantLock. ReentrantLock概况 ReentrantLock是可重入的锁,它不同于内置锁, 它在每次使用都需要显示的加锁和解锁, 而且提供了更高级的特性:公平锁, 定时锁, 有条件锁, 可轮询锁, 可中断锁. 可以有效避免死锁的活跃性问题.ReentrantLock实现了 Lock接口: 复制代码 代码如下: public interface Lock {  

随机推荐