首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > JAVA > J2SE开发 >

Java编程思维里的小例子:使用显式的Lock对象

2013-07-08 
Java编程思想里的小例子:使用显式的Lock对象Java编程思想里的小例子:使用显式的Lock对象,P679,第21.3.2小

Java编程思想里的小例子:使用显式的Lock对象
Java编程思想里的小例子:使用显式的Lock对象,P679,第21.3.2小节,有一个文件AttemptLocking.java如下:

//: concurrency/AttemptLocking.java
// Locks in the concurrent library allow you
// to give up on trying to acquire a lock.
import java.util.concurrent.*;
import java.util.concurrent.locks.*;

public class AttemptLocking {
  private ReentrantLock lock = new ReentrantLock();
  public void untimed() {
    boolean captured = lock.tryLock();
    try {
      System.out.println("tryLock(): " + captured);
    } finally {
      if(captured)
        lock.unlock();
    }
  }
  public void timed() {
    boolean captured = false;
    try {
      captured = lock.tryLock(2, TimeUnit.SECONDS);
    } catch(InterruptedException e) {
      throw new RuntimeException(e);
    }
    try {
      System.out.println("tryLock(2, TimeUnit.SECONDS): " +
        captured);
    } finally {
      if(captured)
        lock.unlock();
    }
  }
  public static void main(String[] args) {
    final AttemptLocking al = new AttemptLocking();
    al.untimed(); // True -- lock is available
    al.timed();   // True -- lock is available
    // Now create a separate task to grab the lock:
    new Thread() {
      { setDaemon(true); }
      public void run() {
        al.lock.lock();
        System.out.println("acquired");
      }
    }.start();
    Thread.yield(); // Give the 2nd task a chance


    al.untimed(); // False -- lock grabbed by task
    al.timed();   // False -- lock grabbed by task
  }
} /* Output:
tryLock(): true
tryLock(2, TimeUnit.SECONDS): true
acquired
tryLock(): false
tryLock(2, TimeUnit.SECONDS): false
*///:~


有几点疑问:
1,我在运行这段代码的时候,很多时候结果不是给出的,而是
tryLock(): true
tryLock(2, TimeUnit.SECONDS): true
acquired
tryLock(): true
tryLock(2, TimeUnit.SECONDS): true
按照书里的说法,也就是说竞争到了锁,但得到这个结果的概率真的挺高的啊
2,但是按照书里的说法,untimed()方法如果拿不到这个锁的话就会继续等待,但怎么看出来的?看不出它哪里在等待啊?untimed()看起来并没有卡在拿锁这个问题上,后台线程不会自动释放锁,它还能返回false,之后timed()方法也返回false
[解决办法]
想法是没错的,但是有一点.


new Thread() {
      { setDaemon(true); }
      public void run() {
        al.lock.lock();
        System.out.println("acquired");
      }
}.start();


谁能保证这个线程一定是在

al.untimed(); // False -- lock grabbed by task
al.timed();   // False -- lock grabbed by task

这两句之前执行?

要达到你的效果,你可能需要设置一个"屏障".这个屏障会阻止主线程的执行直到锁定线程执行完毕,即打印出"acquired"字符串后再执行主线程.

例如,作如下修改.

public static void main(String[] args) throws InterruptedException {
        final AttemptLocking al = new AttemptLocking();
        al.untimed(); // True -- lock is available
        al.timed();   // True -- lock is available
        // Now create a separate task to grab the lock:


        final CountDownLatch latch = new CountDownLatch(1);//1.增加一个"屏障"
        new Thread() {
            {
                setDaemon(false);
            }

            public void run() {
                al.lock.lock();
                System.out.println("acquired");
                latch.countDown();//2.屏障解除
            }
        }.start();
        Thread.yield(); // Give the 2nd task a chance
        latch.await();//3.阻塞在屏障处直到屏障解除
        al.untimed(); // False -- lock grabbed by task
        al.timed();   // False -- lock grabbed by task
    }



上面1,2,3处增加的代码就能保证线程的执行顺序了.

热点排行