Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/macosx/classes/com/apple/concurrent/Dispatch.java
38831 views
/*1* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.apple.concurrent;2627import java.util.concurrent.*;2829/**30* Factory for {@link Executor}s and {@link ExecutorService}s backed by31* libdispatch.32*33* Access is controlled through the Dispatch.getInstance() method, because34* performed tasks occur on threads owned by libdispatch. These threads are35* not owned by any particular AppContext or have any specific context36* classloader installed.37*38* @since Java for Mac OS X 10.6 Update 239*/40public final class Dispatch {41/**42* The priorities of the three default asynchronous queues.43*/44public enum Priority {45LOW(-2), NORMAL(0), HIGH(2); // values from <dispatch/queue.h>4647final int nativePriority;48Priority(final int nativePriority) { this.nativePriority = nativePriority; }49};5051final static Dispatch instance = new Dispatch();5253/**54* Factory method returns an instnace of Dispatch if supported by the55* underlying operating system, and if the caller's security manager56* permits "canInvokeInSystemThreadGroup".57*58* @return a factory instance of Dispatch, or null if not available59*/60public static Dispatch getInstance() {61checkSecurity();62if (!LibDispatchNative.nativeIsDispatchSupported()) return null;6364return instance;65}6667private static void checkSecurity() {68final SecurityManager security = System.getSecurityManager();69if (security != null) security.checkPermission(new RuntimePermission("canInvokeInSystemThreadGroup"));70}7172private Dispatch() { }7374/**75* Creates an {@link Executor} that performs tasks asynchronously. The {@link Executor}76* cannot be shutdown, and enqueued {@link Runnable}s cannot be canceled. Passing null77* returns the {@link Priority.NORMAL} {@link Executor}.78*79* @param priority - the priority of the returned {@link Executor}80* @return an asynchronous {@link Executor}81*/82public Executor getAsyncExecutor(Priority priority) {83if (priority == null) priority = Priority.NORMAL;84final long nativeQueue = LibDispatchNative.nativeCreateConcurrentQueue(priority.nativePriority);85if (nativeQueue == 0L) return null;86return new LibDispatchConcurrentQueue(nativeQueue);87}8889int queueIndex = 0;90/**91* Creates an {@link ExecutorService} that performs tasks synchronously in FIFO order.92* Useful to protect a resource against concurrent modification, in lieu of a lock.93* Passing null returns an {@link ExecutorService} with a uniquely labeled queue.94*95* @param label - a label to name the queue, shown in several debugging tools96* @return a synchronous {@link ExecutorService}97*/98public ExecutorService createSerialExecutor(String label) {99if (label == null) label = "";100if (label.length() > 256) label = label.substring(0, 256);101String queueName = "com.apple.java.concurrent.";102if ("".equals(label)) {103synchronized (this) {104queueName += queueIndex++;105}106} else {107queueName += label;108}109110final long nativeQueue = LibDispatchNative.nativeCreateSerialQueue(queueName);111if (nativeQueue == 0) return null;112return new LibDispatchSerialQueue(nativeQueue);113}114115Executor nonBlockingMainQueue = null;116/**117* Returns an {@link Executor} that performs the provided Runnables on the main queue of the process.118* Runnables submitted to this {@link Executor} will not run until the AWT is started or another native toolkit is running a CFRunLoop or NSRunLoop on the main thread.119*120* Submitting a Runnable to this {@link Executor} does not wait for the Runnable to complete.121* @return an asynchronous {@link Executor} that is backed by the main queue122*/123public synchronized Executor getNonBlockingMainQueueExecutor() {124if (nonBlockingMainQueue != null) return nonBlockingMainQueue;125return nonBlockingMainQueue = new LibDispatchMainQueue.ASync();126}127128Executor blockingMainQueue = null;129/**130* Returns an {@link Executor} that performs the provided Runnables on the main queue of the process.131* Runnables submitted to this {@link Executor} will not run until the AWT is started or another native toolkit is running a CFRunLoop or NSRunLoop on the main thread.132*133* Submitting a Runnable to this {@link Executor} will block until the Runnable has completed.134* @return an {@link Executor} that is backed by the main queue135*/136public synchronized Executor getBlockingMainQueueExecutor() {137if (blockingMainQueue != null) return blockingMainQueue;138return blockingMainQueue = new LibDispatchMainQueue.Sync();139}140}141142143