Java并发编程:核心方法与框架
上QQ阅读APP看书,第一时间看更新

1.1.4 方法acquireUninterruptibly()的使用

方法acquireUninterruptibly()的作用是使等待进入acquire()方法的线程,不允许被中断。

先来看一个能中断的实验。

创建项目Semaphore_acquireUninterruptibly_1,类Service.java代码如下:


        package service;
        import java.util.concurrent.Semaphore;
        public class Service {
            private Semaphore semaphore = new Semaphore(1);
            public void testMethod() {
                try {
                    semaphore.acquire();
                    System.out.println(Thread.currentThread().getName()
                              + " begin timer=" + System.currentTimeMillis());
                    for (int i = 0; i < Integer.MAX_VALUE / 50; i++) {
                        String newString = new String();
                        Math.random();
                    }
                    System.out.println(Thread.currentThread().getName()
                              + "    end timer=" + System.currentTimeMillis());
                    semaphore.release();
                } catch (InterruptedException e) {
                    System.out.println("线程" + Thread.currentThread().getName()
                              + "进入了catch");
                    e.printStackTrace();
                }
            }
        }

线程类代码如图1-9所示。

图1-9 线程类代码

运行类Run.java代码如下:


        package test;
        import service.Service;
        import extthread.ThreadA;
        import extthread.ThreadB;
        public class Run {
            public static void main(String[] args) throws InterruptedException {
              Service service = new Service();
              ThreadA a = new ThreadA(service);
              a.setName("A");
              a.start();
              ThreadB b = new ThreadB(service);
              b.setName("B");
              b.start();
              Thread.sleep(1000);
              b.interrupt();
              System.out.println("main中断了a");
          }
      }

程序运行的效果如图1-10所示。

图1-10 线程B被中断

线程B成功被中断。

那么不能被中断是什么效果呢?

创建项目Semaphore_acquireUninterruptibly_2,将Semaphore_acquireUninterruptibly_1项目中的所有源代码复制到Semaphore_acquireUninterruptibly_2中,更改Service.java文件代码如下:


        package service;
        import java.util.concurrent.Semaphore;
        public class Service {
            private Semaphore semaphore = new Semaphore(1);
            public void testMethod() {
                semaphore.acquireUninterruptibly();
                System.out.println(Thread.currentThread().getName() + " begin timer="
                        + System.currentTimeMillis());
                for (int i = 0; i < Integer.MAX_VALUE / 50; i++) {
                    String newString = new String();
                    Math.random();
                }
                System.out.println(Thread.currentThread().getName() + "    end timer="
                        + System.currentTimeMillis());
                semaphore.release();
            }
        }

程序运行后的效果如图1-11所示。

图1-11 线程B没有被中断

acquireUninterruptibly()方法还有重载的写法acquire-Uninterruptibly(int permits),此方法的作用是在等待许可的情况下不允许中断,如果成功获得锁,则取得指定的permits许可个数。