并发库应用之四 & 线程锁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场景应用   

 

posted @ 2017-03-08 17:58  星火燎原智勇  阅读(378)  评论(0编辑  收藏  举报