并发库应用之四 & 线程锁Lock应用

  Java5的线程并发库中,提供了相应的线程锁接口Lock来帮助我们同步处理。Lock比传统线程模型中的synchronized更加面向对象,锁本身也是一个对象,两个线程执行的代码要实现同步互斥效果,就要使用同一个锁对象。锁要上在要操作的资源类的内部方法中,而不是线程代码中。

java.util.concurrent.locks在并发编程中很常用的实用接口。

        |----Lock          实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作

        |----ReadWriteLock  维护了一对相关的,一个用于只读操作,另一个用于写入操作

        |----Condition      将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待

  本篇主要讲解与Lock有关内容,故一下主要针对Lock进行阐述:

  接口:

  public interface Lock

  所有已知实现类:

  ReentrantLock

  ReentrantReadWriteLock.ReadLock

  ReentrantReadWriteLock.WriteLock

  随着灵活性的增加,也带来了更多的责任。不使用块结构锁就失去了使用 synchronized 方法和语句时会出现的锁自动释放功能。在大多数情况下,应该使用以下语句:

    Lock lk = ...;
    lk.lock();
    try {
        // access the resource protected by this lock
     } finally {
        lk.unlock();
    }

  锁定和取消锁定出现在不同作用范围中时,必须谨慎地确保保持锁定时所执行的所有代码用 try-finally 或 try-catch 加以保护,以确保在必要时释放锁。

  打印字符串使用锁机制进行打印,使其内部线程之间互斥,源代码如下:

 1 import java.util.concurrent.ExecutorService;
 2 import java.util.concurrent.Executors;
 3 import java.util.concurrent.locks.Lock;
 4 import java.util.concurrent.locks.ReentrantLock;
 5
 6 public class LockTest {
 7     public static void main(String[] args) {
 8         final Business business = new Business();
 9         ExecutorService executor = Executors.newFixedThreadPool(3);
10         for (int i = 0; i < 3; i++) {
11             executor.execute(
12                     new Runnable() {
13                         public void run() {
14                             business.service();
15                         }
16                     }
17
18             );
19         }
20         executor.shutdown();
21     }
22
23     private static class Business {
24         private int count;
25         Lock lock = new ReentrantLock();
26
27         public void service() {
28             lock.lock();
29             try {
30                 count++;
31                 try {
32                     Thread.sleep(1);
33                 } catch (InterruptedException e) {
34                     e.printStackTrace();
35                 }
36                 System.out.println(count);
37             } catch (RuntimeException e) {
38                 e.printStackTrace();
39             } finally {
40                 lock.unlock();
41             }
42         }
43     }
44 }

运行结果如下所示:

提示:更加常用且重要的锁为读写锁,具体详情请查看我的下一篇博客:并发库应用之五 & ReadWriteLock场景应用

时间: 2024-11-03 03:41:01

并发库应用之四 & 线程锁Lock应用的相关文章

Android多线程研究(9)——线程锁Lock

在前面我们在解决线程同步问题的时候使用了synchronized关键字,今天我们来看看Java 5.0以后提供的线程锁Lock. Lock接口的实现类提供了比使用synchronized关键字更加灵活和广泛的锁定对象操作,而且是以面向对象的方式进行对象加锁. @Override public void run() { while(true){ Lock lock = new ReentrantLock(); try { lock.lock(); Thread.sleep(new Random()

JDK5.0 特性-线程锁Lock

来自:http://www.cnblogs.com/taven/archive/2011/12/17/2291470.html 1 import java.util.concurrent.ExecutorService; 2 3 import java.util.concurrent.Executors; 4 5 import java.util.concurrent.Future; 6 7 import java.util.concurrent.locks.Lock; 8 9 import j

并发编程—4显式锁 Lock

目录 4.显式锁 Lock 4.1 概念 内置锁 vs 显示锁 可重入锁 vs 不可重入锁 公平锁 vs 非公平锁 读锁 vs 写锁 4.2 ReentrantLock源码解读 4.显式锁 Lock 4.1 概念 内置锁 vs 显示锁 synchronize是java语言层面实现的锁,称为内置锁.使用方便代码简洁,而且在jdk新版本优化后,性能也得到了很大的提高.synchronize是一个可重入锁.而Lock是jdk提供开发者是用的一个显式锁.通过lock()和unlock()方法加锁和释放锁

【Java并发系列04】线程锁synchronized和Lock和volatile和Condition

img { border: solid 1px } 一.前言 多线程怎么防止竞争资源,即防止对同一资源进行并发操作,那就是使用加锁机制.这是Java并发编程中必须要理解的一个知识点.其实使用起来还是比较简单,但是一定要理解. 有几个概念一定要牢记: 加锁必须要有锁 执行完后必须要释放锁 同一时间.同一个锁,只能有一个线程执行 二.synchronized synchronized的特点是自动释放锁,作用在方法时自动获取锁,任意对象都可做为锁,它是最常用的加锁机制,锁定几行代码,如下: //---

线程锁-LOCK

from threading import Thread,Lockimport timea=10b=10lock=Lock()def fun(): # lock.acquire() global a global b a+=1 time.sleep(1) b+=1 # lock.release() print("-a{}--b{}-->".format(a,b)) if __name__=="__main__": start=time.time() l=[]

Java线程与并发库高级应用-线程范围内共享数据ThreadLocal类

1.线程范围内共享变量 1.1 前奏: 使用一个Map来实现线程范围内共享变量 public class ThreadScopeShareData { static Map<Thread, Integer> dataMap = new HashMap<Thread, Integer>(); public static void main(String[] args) { for (int i = 0; i < 2; i++) { new Thread(new Runnable

Java多线程与并发库高级应用-线程池

线程池 线程池的思想  线程池的概念与Executors类的应用 > 创建固定大小的线程池 > 创建缓存线程池 > 创建单一线程池(如何实现线程死掉后重新启动?) 关闭线程池 > shutdown 与 shutdownNow的比较 用线程池启动定时器 > 调用ScheduleExecutorService 的 schedule 方法,返回的ScheduleFuture对象可以取消任务. > 支持间隔重复任务的定时方式,不直接支持决定定时的方法,需要转换成相对时间方式.

线程高级应用-心得5-java5线程并发库中Lock和Condition实现线程同步通讯

1.Lock相关知识介绍 好比我同时种了几块地的麦子,然后就等待收割.收割时,则是哪块先熟了,先收割哪块. 下面举一个面试题的例子来引出Lock缓存读写锁的案例,一个load()和get()方法返回值为空时的情况:load()的返回值是一个代理对象,而get()却是一个实实在在的对象:所以当返回对象为空是,get()返回null,load()返回一个异常对象:具体分析如下: 一个读写锁的缓存库案例:用上面那道面试题分析则很好理解: 线程阻塞问题:运用多个Condition对象解决 2. Lock

多线程篇八:线程锁

1.线程锁Lock/ReentrantLock package com.test.lock; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; //线程锁,通常用于替换synchronized,比synchronized更加面向对象 public class LockTest { static class Outputer{ Lock locks=new Reentra