• LockSupport的park和unpark的基本使用,以及对线程中断的响应性


    /**
    * Disables the current thread for thread scheduling purposes unless the
    * permit is available.
    *
    * <p>If the permit is available then it is consumed and the call returns
    * immediately; otherwise
    * the current thread becomes disabled for thread scheduling
    * purposes and lies dormant until one of three things happens:
    *
    * <ul>
    * <li>Some other thread invokes {@link #unpark unpark} with the
    * current thread as the target; or
    *
    * <li>Some other thread {@linkplain Thread#interrupt interrupts}
    * the current thread; or
    *
    * <li>The call spuriously (that is, for no reason) returns.
    * </ul>
    *
    * <p>This method does <em>not</em> report which of these caused the
    * method to return. Callers should re-check the conditions which caused
    * the thread to park in the first place. Callers may also determine,
    * for example, the interrupt status of the thread upon return.
    *
    * @param blocker the synchronization object responsible for this
    * thread parking
    * @since 1.6
    */
    public static void park(Object blocker) 

    /**
    * Makes available the permit for the given thread, if it
    * was not already available. If the thread was blocked on
    * {@code park} then it will unblock. Otherwise, its next call
    * to {@code park} is guaranteed not to block. This operation
    * is not guaranteed to have any effect at all if the given
    * thread has not been started.
    *
    * @param thread the thread to unpark, or {@code null}, in which case
    * this operation has no effect
    */
    public static void unpark(Thread thread)

    LockSupport是JDK中比较底层的类,用来创建锁和其他同步工具类的基本线程阻塞原语。java锁和同步器框架的核心 AQS: AbstractQueuedSynchronizer,就是通过调用 LockSupport .park()和 LockSupport .unpark()实现线程的阻塞和唤醒 的。 LockSupport 很类似于二元信号量(只有1个许可证可供使用),如果这个许可还没有被占用,当前线程获取许可并继 续 执行;如果许可已经被占用,当前线 程阻塞,等待获取许可。

    public static void main(String[] args)
    {
         LockSupport.park();
         System.out.println("block.");
    }

    运行该代码,可以发现主线程一直处于阻塞状态。因为 许可默认是被占用的 ,调用park()时获取不到许可,所以进入阻塞状态。

    如下代码:先释放许可,再获取许可,主线程能够正常终止。LockSupport许可的获取和释放,一般来说是对应的,如果多次unpark,只有一次park也不会出现什么问题,结果是许可处于可用状态。

    public static void main(String[] args)
    {
         Thread thread = Thread.currentThread();
         LockSupport.unpark(thread);//释放许可
         LockSupport.park();// 获取许可
         System.out.println("b");
    }

    LockSupport是可不重入 的,如果一个线程连续2次调用 LockSupport .park(),那么该线程一定会一直阻塞下去。

    public static void main(String[] args) throws Exception
    {
    	Thread thread = Thread.currentThread();
    	
    	LockSupport.unpark(thread);
    	
    	System.out.println("a");
    	LockSupport.park();
    	System.out.println("b");
    	LockSupport.park();
    	System.out.println("c");
    }

    这段代码打印出a和b,不会打印c,因为第二次调用park的时候,线程无法获取许可出现死锁。

    下面我们来看下LockSupport对应中断的响应性

    public static void t2() throws Exception
    {
    	Thread t = new Thread(new Runnable()
    	{
    		private int count = 0;
    
    		@Override
    		public void run()
    		{
    			long start = System.currentTimeMillis();
    			long end = 0;
    
    			while ((end - start) <= 1000)
    			{
    				count++;
    				end = System.currentTimeMillis();
    			}
    
    			System.out.println("after 1 second.count=" + count);
    
    		//等待或许许可
    			LockSupport.park();
    			System.out.println("thread over." + Thread.currentThread().isInterrupted());
    
    		}
    	});
    
    	t.start();
    
    	Thread.sleep(2000);
    
    	// 中断线程
    	t.interrupt();
    
    	
    	System.out.println("main over");
    }

    最终线程会打印出thread over.true。这说明 线程如果因为调用park而阻塞的话,能够响应中断请求(中断状态被设置成true),但是不会抛出InterruptedException 。

  • 相关阅读:
    python类的继承
    Numpy float64和Python float是一样的
    ndarray的用法总结
    pandas的Panel类型dtype
    C++中类的前向声明
    numpy的searchsorted细品
    发现Boost官方文档的一处错误(numpy的ndarray)
    C++读取dll文件所在目录
    64位的pyd报"ImportError: No module named"错误
    WIN32,_WIN32_WIN64
  • 原文地址:https://www.cnblogs.com/zhaoxinshanwei/p/7053537.html
Copyright © 2020-2023  润新知