当前位置:网站首页>[high concurrency] deeply analyze the callable interface
[high concurrency] deeply analyze the callable interface
2022-06-27 14:51:00 【Retirement procedure ape】
This article is pure dry goods , In depth analysis from the perspective of source code Callable Interface , I hope you will step down , Open your IDE, Follow the article to see the source code , I believe you will gain a lot .
1.Callable The interface is introduced
Callable Interface is JDK1.5 New generic interface , stay JDK1.8 in , Declared as a functional interface , As shown below .
@FunctionalInterface
public interface Callable<V> {
V call() throws Exception;
}
Copy code stay JDK 1.8 Only one method's interface is declared as a functional interface in , Functional interfaces can be used @FunctionalInterface To modify , You can also not use @FunctionalInterface To modify . As long as an interface contains only one method , that , This interface is a functional interface .
stay JDK in , Realization Callable The subclass of the interface is shown in the figure below .

The default subclass hierarchy diagram is not clear , here , Can pass IDEA Right click Callable Interface , choice “Layout” To specify the Callable Interface implementation, different structure of class diagram , As shown below .

here , You can choose “Organic Layout” Options , After selection Callable The structure of subclasses of interfaces is shown in the figure below .

In the realization of Callable In subclasses of interfaces , There are several important classes , As shown in the figure below .

Namely :Executors Static inner class in class :PrivilegedCallable、PrivilegedCallableUsingCurrentClassLoader、RunnableAdapter and Task Under class TaskCallable.
2. Realization Callable Analysis of important classes of interfaces
Next , The main classes analyzed are :PrivilegedCallable、PrivilegedCallableUsingCurrentClassLoader、RunnableAdapter and Task Under class TaskCallable. Although these classes are rarely used directly in practical work , But as a qualified Development Engineer , The setting is for baldness senior experts , Understanding and mastering the implementation of these classes will help you further understand Callable Interface , And improve professional skills ( Another batch of hair loss , Whoahaha ...).
- PrivilegedCallable
PrivilegedCallable Class is Callable A special implementation class for interfaces , It shows that Callable Objects have certain privileges to access certain resources of the system ,PrivilegedCallable The source code for the class is as follows .
/**
* A callable that runs under established access control settings
*/
static final class PrivilegedCallable<T> implements Callable<T> {
private final Callable<T> task;
private final AccessControlContext acc;
PrivilegedCallable(Callable<T> task) {
this.task = task;
this.acc = AccessController.getContext();
}
public T call() throws Exception {
try {
return AccessController.doPrivileged(
new PrivilegedExceptionAction<T>() {
public T run() throws Exception {
return task.call();
}
}, acc);
} catch (PrivilegedActionException e) {
throw e.getException();
}
}
}
Copy code from PrivilegedCallable Class source code , Can be PrivilegedCallable See it as right Callable Interface encapsulation , And this class also inherits Callable Interface .
stay PrivilegedCallable Class has two member variables , Namely Callable The instance object of the interface and AccessControlContext class , As shown below .
private final Callable<T> task;
private final AccessControlContext acc;
Copy code among ,AccessControlContext Class can be understood as a context class with system resource access decision , Through this class, you can access specific resources of the system . Through the class construction method, we can see that , In instantiation AccessControlContext Class , Just pass it on Callable Object of interface subclass , As shown below .
PrivilegedCallable(Callable<T> task) {
this.task = task;
this.acc = AccessController.getContext();
}
Copy code AccessControlContext Class objects are created through AccessController Class getContext() Method acquired , here , see AccessController Class getContext() Method , As shown below .
public static AccessControlContext getContext(){
AccessControlContext acc = getStackAccessControlContext();
if (acc == null) {
return new AccessControlContext(null, true);
} else {
return acc.optimize();
}
}
Copy code adopt AccessController Of getContext() The method shows that , First, through getStackAccessControlContext() Method to get AccessControlContext Object instances . If you get AccessControlContext Object instance is empty , By calling AccessControlContext Class constructor instantiation , otherwise , call AccessControlContext Object instance optimize() Method returns AccessControlContext Object instances .
here , Let's take a look first getStackAccessControlContext() What the hell is the method .
private static native AccessControlContext getStackAccessControlContext();
Copy code It turned out to be a local method , Method literally means to get the decision context object that can access the system stack .
Next , We go back to PrivilegedCallable Class call() Method , As shown below .
public T call() throws Exception {
try {
return AccessController.doPrivileged(
new PrivilegedExceptionAction<T>() {
public T run() throws Exception {
return task.call();
}
}, acc);
} catch (PrivilegedActionException e) {
throw e.getException();
}
}
Copy code By calling AccessController.doPrivileged() Method , Pass on PrivilegedExceptionAction. Interface objects and AccessControlContext object , And finally returns the generic instance object .
First , look down AccessController.doPrivileged() Method , As shown below .
@CallerSensitive
public static native <T> T
doPrivileged(PrivilegedExceptionAction<T> action,
AccessControlContext context)
throws PrivilegedActionException;
Copy code You can see , Another local approach . in other words , The final implementation will be PrivilegedExceptionAction Interface objects and AccessControlContext Object instance is passed to the local method execution . And in PrivilegedExceptionAction Of the interface object run() Call in method Callable Interface call() Method to execute the final business logic , And return the generic object .
- PrivilegedCallableUsingCurrentClassLoader
This class is represented as running under the specific access control that has been established and the current class loader Callable class , The source code is as follows .
/**
* A callable that runs under established access control settings and
* current ClassLoader
*/
static final class PrivilegedCallableUsingCurrentClassLoader<T> implements Callable<T> {
private final Callable<T> task;
private final AccessControlContext acc;
private final ClassLoader ccl;
PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
this.task = task;
this.acc = AccessController.getContext();
this.ccl = Thread.currentThread().getContextClassLoader();
}
public T call() throws Exception {
try {
return AccessController.doPrivileged(
new PrivilegedExceptionAction<T>() {
public T run() throws Exception {
Thread t = Thread.currentThread();
ClassLoader cl = t.getContextClassLoader();
if (ccl == cl) {
return task.call();
} else {
t.setContextClassLoader(ccl);
try {
return task.call();
} finally {
t.setContextClassLoader(cl);
}
}
}
}, acc);
} catch (PrivilegedActionException e) {
throw e.getException();
}
}
}
Copy code This class is easy to understand , First , Three member variables are defined in the class , As shown below .
private final Callable<T> task;
private final AccessControlContext acc;
private final ClassLoader ccl;
Copy code Next , Injected by constructor Callable object , In the constructor , First, get the instance of the system security manager object , Check whether there is access through the system security manager object instance ClassLoader And set up ContextClassLoader Authority . And assign values to three member variables in the construction method , As shown below .
PrivilegedCallableUsingCurrentClassLoader(Callable<T> task) {
SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
sm.checkPermission(new RuntimePermission("setContextClassLoader"));
}
this.task = task;
this.acc = AccessController.getContext();
this.ccl = Thread.currentThread().getContextClassLoader();
}
Copy code Next , By calling call() Methods to perform specific business logic , As shown below .
public T call() throws Exception {
try {
return AccessController.doPrivileged(
new PrivilegedExceptionAction<T>() {
public T run() throws Exception {
Thread t = Thread.currentThread();
ClassLoader cl = t.getContextClassLoader();
if (ccl == cl) {
return task.call();
} else {
t.setContextClassLoader(ccl);
try {
return task.call();
} finally {
t.setContextClassLoader(cl);
}
}
}
}, acc);
} catch (PrivilegedActionException e) {
throw e.getException();
}
}
Copy code stay call() Method is also called AccessController Class doPrivileged, Pass on PrivilegedExceptionAction The instance object of the interface and AccessControlContext Object instance of class .
The specific execution logic is : stay PrivilegedExceptionAction Object's run() Method ContextClassLoader object , If you get in the constructor ClassLoader Object is the same as ContextClassLoader Objects are the same object ( Not just object instances , And the memory address is the same ), Call directly Callable Object's call() Method returns the result . otherwise , take PrivilegedExceptionAction Object's run() Method of the current thread ContextClassLoader Set to the class loader object obtained in the constructor , Next , Call again Callable Object's call() Method returns the result . Finally, the current thread's ContextClassLoader Reset to the previous ContextClassLoader.
- RunnableAdapter
RunnableAdapter Class is simpler , Given the tasks and results to run , Run the given task and return the given result , The source code is as follows .
/**
* A callable that runs given task and returns given result
*/
static final class RunnableAdapter<T> implements Callable<T> {
final Runnable task;
final T result;
RunnableAdapter(Runnable task, T result) {
this.task = task;
this.result = result;
}
public T call() {
task.run();
return result;
}
}
Copy code - TaskCallable
TaskCallable Class is javafx.concurrent.Task Static inner class of class ,TaskCallable Class mainly implements Callable Interface and is defined as FutureTask Class , And in this class we are allowed to intercept call() Method to update task The status of the task . The source code is as follows .
private static final class TaskCallable<V> implements Callable<V> {
private Task<V> task;
private TaskCallable() { }
@Override
public V call() throws Exception {
task.started = true;
task.runLater(() -> {
task.setState(State.SCHEDULED);
task.setState(State.RUNNING);
});
try {
final V result = task.call();
if (!task.isCancelled()) {
task.runLater(() -> {
task.updateValue(result);
task.setState(State.SUCCEEDED);
});
return result;
} else {
return null;
}
} catch (final Throwable th) {
task.runLater(() -> {
task._setException(th);
task.setState(State.FAILED);
});
if (th instanceof Exception) {
throw (Exception) th;
} else {
throw new Exception(th);
}
}
}
}
Copy code from TaskCallable The source code of the class shows that , Only one... Is defined Task A member variable of type . The main analysis is as follows TaskCallable Class call() Method .
When the execution of the program enters call() When the method is used , First of all, will task Object's started Property is set to true, The task has begun , And set the state of the task to State.SCHEDULED and State.RUNNING, Trigger the scheduling event and the running event of the task in turn . As shown below .
task.started = true;
task.runLater(() -> {
task.setState(State.SCHEDULED);
task.setState(State.RUNNING);
});
Copy code Next , stay try Code block Task Object's call() Method , Returns a generic object . If the mission is not cancelled , Then update the task's cache , Will call call() Method returns a generic object bound to Task Object ObjectProperty In the object , among ,ObjectProperty stay Task The definitions in the class are as follows .
private final ObjectProperty<V> value = new SimpleObjectProperty<>(this, "value");
Copy code Next , Set the status of the task to success . As shown below .
try {
final V result = task.call();
if (!task.isCancelled()) {
task.runLater(() -> {
task.updateValue(result);
task.setState(State.SUCCEEDED);
});
return result;
} else {
return null;
}
}
Copy code If the program throws an exception or error , Will enter catch() Code block , Set up Task Object's Exception And set the status to State.FAILED, That is to mark the task as failed . Next , Determine the type of exception or error , If it is Exception Exception of type , Then it will be changed into Exception Type and throw . otherwise , Encapsulate an exception or error as Exception Object and throw , As shown below .
catch (final Throwable th) {
task.runLater(() -> {
task._setException(th);
task.setState(State.FAILED);
});
if (th instanceof Exception) {
throw (Exception) th;
} else {
throw new Exception(th);
}
}
Copy code remember : Where you are better than others , It's not how many years you've been doing it CRUD Work , It's that you have more in-depth skills than others . Don't stay on the road all the time CRUD The surface work of , Understand and master the underlying principles and familiar with the source code implementation , And form their own abstract thinking ability , Flexible use , It's you who break through the bottleneck , The important direction to stand out !
Last , As a qualified ( The hairline is relatively high ) Developer or senior ( Baldness ) For engineers and architects , Understand the principle and master the source code , And form their own abstract thinking ability , Flexibility is a skill you must master .
边栏推荐
- Teach you how to realize pynq-z2 bar code recognition
- 注解学习总结
- PR second training notes
- Hyperledger Fabric 2. X custom smart contract
- [business security-02] business data security test and example of commodity order quantity tampering
- Handling methods for NVIDIA deepstream running delay, jamming and crash
- 事务的四大特性
- 请求一下子太多了,数据库危
- Synchronized and lock escalation
- [business security 03] password retrieval business security and interface parameter account modification examples (based on the metinfov4.0 platform)
猜你喜欢

Teach you how to realize pynq-z2 bar code recognition

volatile与JMM
![[business security 03] password retrieval business security and interface parameter account modification examples (based on the metinfov4.0 platform)](/img/29/73c381f14a09ecaf36a98d67d76720.png)
[business security 03] password retrieval business security and interface parameter account modification examples (based on the metinfov4.0 platform)

What are the operating modes of the live app? What mode should we choose?

Design and implementation of food recipe and ingredients website based on vue+node+mysql

请求一下子太多了,数据库危

Rereading the classic: the craft of research (1)

HTTP Caching Protocol practice

Unity3d best practices: folder structure and source control
![[WUSTCTF2020]girlfriend](/img/a8/33fe5feb7bcbb73ba26a94d226cc4d.png)
[WUSTCTF2020]girlfriend
随机推荐
[advanced MySQL] MTS master-slave synchronization principle and Practice Guide (7)
[business security-04] universal user name and universal password experiment
Nvidia Deepstream 运行延迟,卡顿,死机处理办法
【业务安全-04】万能用户名及万能密码实验
Library management system
隐私计算FATE-离线预测
What is the London Silver code
[daily 3 questions (3)] maximum number of balls in the box
[xman2018 qualifying] pass
Redis 主从复制、哨兵模式、Cluster集群
LVI: feature extraction and sorting of lidar subsystem
Daily 3 questions (1): find the nearest point with the same X or Y coordinate
【每日3题(3)】盒子中小球的最大数量
CAS comparison and exchange
enable_ if
关于 Spartacus 的 sitemap.xml 问题
ThreadLocal之强、弱、軟、虛引用
Redis持久化
Lei Jun lost another great general, and liweixing, the founding employee of Xiaomi No. 12, left his post. He once had porridge to create Xiaomi; Intel's $5.4 billion acquisition of tower semiconductor
Jupiter core error