`

使用Executor

 
阅读更多
相关代码:
public class CachedThreadPool {
public static void main(String[] args) {
ExecutorService exec = Executors.newSingleThreadExecutor();
for (int i = 0; i < 5; i++){
exec.execute(new LiftOff());
System.out.println("");
}
exec.shutdown();
}
}



Executor在java 5/6中是启动任务(线程)的优选方法;

主要类描述:

1.
public interface ExecutorService
extends Executor

An Executor that provides methods to manage termination and methods that can produce a Future for tracking progress of one or more asynchronous tasks.

An ExecutorService can be shut down, which will cause it to stop accepting new tasks. After being shut down, the executor will eventually terminate, at which point no tasks are actively executing, no tasks are awaiting execution, and no new tasks can be submitted.

(1)void execute(Runnable command)
          Executes the given command at some time in the future.
  这个是从Executor接口中继承的方法
(2)shutdown

void shutdown()

    Initiates an orderly shutdown in which previously submitted tasks are executed, but no new tasks will be accepted. Invocation has no additional effect if already shut down.

调用该方法之后,将不会接受新的线程对象,原来的线程对象将会执行完毕。
(3)
awaitTermination

boolean awaitTermination(long timeout,
                         TimeUnit unit)
                         throws InterruptedException

    Blocks until all tasks have completed execution after a shutdown request, or the timeout occurs, or the current thread is interrupted, whichever happens first.

    Parameters:
        timeout - the maximum time to wait
        unit - the time unit of the timeout argument
    Returns:
        true if this executor terminated and false if the timeout elapsed before termination
如果所有的任务在规定的时间到达之前全部结束,则返回true。否则返回false。


2.
java.lang.Object
  extended by java.util.concurrent.Executors

public class Executors
extends Object

(1)newCachedThreadPool

public static ExecutorService newCachedThreadPool()

    Creates a thread pool that creates new threads as needed, but will reuse previously constructed threads when they are available. These pools will typically improve the performance of programs that execute many short-lived asynchronous tasks. Calls to execute will reuse previously constructed threads if available. If no existing thread is available, a new thread will be created and added to the pool. Threads that have not been used for sixty seconds are terminated and removed from the cache. Thus, a pool that remains idle for long enough will not consume any resources. Note that pools with similar properties but different details (for example, timeout parameters) may be created using ThreadPoolExecutor constructors.

    Returns:
        the newly created thread pool
该方法通常会创建与所需数量相同的线程。在回收旧线程时,不会创建新的线程,这个方法是首选。当这个方法不能满足需要时,才考虑使用其他方法。

(2)
newFixedThreadPool

public static ExecutorService newFixedThreadPool(int nThreads)

    Creates a thread pool that reuses a fixed set of threads operating off a shared unbounded queue. If any thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.

    Parameters:
        nThreads - the number of threads in the pool
    Returns:
        the newly created thread pool

该方法是创建一个含有固定数量线程的线程池

(3)
newSingleThreadExecutor

public static ExecutorService newSingleThreadExecutor()

    Creates an Executor that uses a single worker thread operating off an unbounded queue. (Note however that if this single thread terminates due to a failure during execution prior to shutdown, a new one will take its place if needed to execute subsequent tasks.) Tasks are guaranteed to execute sequentially, and no more than one task will be active at any given time. Unlike the otherwise equivalent newFixedThreadPool(1) the returned executor is guaranteed not to be reconfigurable to use additional threads.
如果向它提交了多个任务,那么这些任务将排队,每个任务都会在下一个任务开始之前运行结束,所有任务将使用相同的线程。即,它会序列化所有提交给它的任务。


3
 
extended by java.util.concurrent.locks.ReentrantLock

public class ReentrantLock
extends Object
implements Lock, Serializable

A reentrant mutual exclusion Lock with the same basic behavior and semantics as the implicit monitor lock accessed using synchronized methods and statements, but with extended capabilities.

A ReentrantLock is owned by the thread last successfully locking, but not yet unlocking it. A thread invoking lock will return, successfully acquiring the lock, when the lock is not owned by another thread. The method will return immediately if the current thread already owns the lock. This can be checked using methods isHeldByCurrentThread(), and getHoldCount().

(1)
lock

public void lock()

    Acquires the lock.

    Acquires the lock if it is not held by another thread and returns immediately, setting the lock hold count to one.

    If the current thread already holds the lock then the hold count is incremented by one and the method returns immediately.

    If the lock is held by another thread then the current thread becomes disabled for thread scheduling purposes and lies dormant until the lock has been acquired, at which time the lock hold count is set to one.
(2)
unlock

public void unlock()

    Attempts to release this lock.

    If the current thread is the holder of this lock then the hold count is decremented. If the hold count is now zero then the lock is released. If the current thread is not the holder of this lock then IllegalMonitorStateException is thrown.

例如:
public static int m=0;
private static Lock lock = new ReentrantLock();


public static int getI(){
lock.lock();
try{
m++;
m++;
return m;
}finally{
lock.unlock();
}

}

注意:return 要放到try块中,unlock方法要放到finally块中。如果在使用synchronized失败了,那么就会抛出一个异常,但是没有机会做任何清理工作。lock就可以做到。

(3)
tryLock

public boolean tryLock()

    Acquires the lock only if it is not held by another thread at the time of invocation.

    Acquires the lock if it is not held by another thread and returns immediately with the value true, setting the lock hold count to one. Even when this lock has been set to use a fair ordering policy, a call to tryLock() will immediately acquire the lock if it is available, whether or not other threads are currently waiting for the lock. This "barging" behavior can be useful in certain circumstances, even though it breaks fairness. If you want to honor the fairness setting for this lock, then use tryLock(0, TimeUnit.SECONDS) which is almost equivalent (it also detects interruption).

    If the current thread already holds this lock then the hold count is incremented by one and the method returns true.

    If the lock is held by another thread then this method will return immediately with the value false.

    Specified by:
        tryLock in interface Lock

    Returns:
        true if the lock was free and was acquired by the current thread, or the lock was already held by the current thread; and false otherwise.
这个方法是抢先获得锁。有个缺点,如果其他线程已经获得锁,那么它放回false后,继续执行下面的代码,达不到同步的作用,还是用lock吧

(4)
tryLock

public boolean tryLock(long timeout,
                       TimeUnit unit)
                throws InterruptedException

    Acquires the lock if it is not held by another thread within the given waiting time and the current thread has not been interrupted.

    Acquires the lock if it is not held by another thread and returns immediately with the value true, setting the lock hold count to one. If this lock has been set to use a fair ordering policy then an available lock will not be acquired if any other threads are waiting for the lock. This is in contrast to the tryLock() method. If you want a timed tryLock that does permit barging on a fair lock then combine the timed and un-timed forms together:

    if (lock.tryLock() || lock.tryLock(timeout, unit) ) { ... }
    

该方法的意思是在给定的时间内,去公平竞争锁。如果时间到还没有获得锁,则返回false。和synchronized不同,如果访问对象的某个synchronized方法,其它线程就不能访问该对象的所有synchronized方法。但是,如果没有synchronized而是在方法内部用了lock,就不会出现这种现象,其它线程还可以访问该对象的其它内部还有lock的方法。例如:


public class AttemptLocking {
private ReentrantLock lock = new ReentrantLock();

public void untimed() throws Exception {
boolean captured = lock.tryLock();
try {
System.out.println("tryLock(): ");
Thread.sleep(5 * 1000);
System.out.println("时间已过");
} finally {
if (captured)
lock.unlock();
}
}

public void timed() {
boolean captured = false;
try {
captured = lock.tryLock(6, TimeUnit.SECONDS);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
try {
System.out.println("tryLock(10, TimeUnit.SECONDS): " + captured);
} finally {
if (captured) {

lock.unlock();
} else {
System.out.println("没有执行");
}
}
}

public void f() {
System.out.println("其他方法");
}

public static void main(String[] args) {
final AttemptLocking al = new AttemptLocking();
ExecutorService exec = Executors.newCachedThreadPool();

Runnable r1 = new Runnable() {

@Override
public void run() {
try {
al.untimed();
} catch (Exception e) {
e.printStackTrace();
}
}
};
Runnable r2 = new Runnable() {

@Override
public void run() {
al.timed();
}
};
Runnable r3 = new Runnable() {

@Override
public void run() {
al.f();
}
};
exec.execute(r1);
exec.execute(r3);
exec.execute(r2);
exec.shutdown();
}
}



4.
java.util.concurrent
Interface Future<V>

public interface Future<V>

A Future represents the result of an asynchronous computation. Methods are provided to check if the computation is complete, to wait for its completion, and to retrieve the result of the computation. The result can only be retrieved using method get when the computation has completed, blocking if necessary until it is ready. Cancellation is performed by the cancel method. Additional methods are provided to determine if the task completed normally or was cancelled. Once a computation has completed, the computation cannot be cancelled. If you would like to use a Future for the sake of cancellability but not provide a usable result, you can declare types of the form Future<?> and return null as a result of the underlying task.

Sample Usage (Note that the following classes are all made-up.)

interface ArchiveSearcher { String search(String target); }
class App {
   ExecutorService executor = ...
   ArchiveSearcher searcher = ...
   void showSearch(final String target) throws InterruptedException {
     Future<String> future = executor.submit(new Callable<String>() {
         public String call() { return searcher.search(target); }
     });
     displayOtherThings(); // do other things while searching
     try {
       displayText(future.get()); // use future
     } catch (ExecutionException ex) { cleanup(); return; }
   }
}

相关方法:
(1)cancel

boolean cancel(boolean mayInterruptIfRunning)

    Attempts to cancel execution of this task. This attempt will fail if the task has already completed, already been cancelled, or could not be cancelled for some other reason. If successful, and this task has not started when cancel is called, this task should never run. If the task has already started, then the mayInterruptIfRunning parameter determines whether the thread executing this task should be interrupted in an attempt to stop the task.

    Parameters:
        mayInterruptIfRunning - true if the thread executing this task should be interrupted; otherwise, in-progress tasks are allowed to complete
    Returns:
        false if the task could not be cancelled, typically because it has already completed normally; true otherwise

5.如果希望完成任务时,能够返回一个值,那么可以实现Callable接口而不是Runnable接口。例如:
class TaskWithResult implements Callable<String> {
private int id;

public TaskWithResult(int id) {
this.id = id;
}

public String call() {
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "result of TaskWithResult " + id;
}
}

public class CallableDemo {
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
ArrayList<Future<String>> results = new ArrayList<Future<String>>();
for (int i = 0; i < 10; i++)
results.add(exec.submit(new TaskWithResult(i)));
        for(int i=0;i<10;i++){
        System.out.println("hahah"+i);
        }
for (Future<String> fs : results)
try {
// get() blocks until completion:
System.out.println(fs.get());
} catch (InterruptedException e) {
System.out.println(e);
return;
} catch (ExecutionException e) {
System.out.println(e);
} finally {
exec.shutdown();
}
}
}
分享到:
评论

相关推荐

    Executor框架使用详解

    总结来说,Executor框架是Java并发编程的基石,通过合理配置和使用Executor,可以有效地管理线程资源,提高系统的并发性和响应性。深入学习和理解Executor框架,对于提升Java并发程序的设计和实现能力至关重要。

    Executor快速打开应用

    为了更好地使用Executor,你需要了解如何配置和管理启动项。这通常包括以下步骤: 1. 打开Executor配置文件,可以是.ini或.xml格式。 2. 添加新的启动项,输入应用的完整路径或者别名。 3. 可选地,为启动项设置...

    PyPI 官网下载 | executor-21.1.tar.gz

    为了使用executor-21.1,你需要首先从PyPI下载并安装这个包。在命令行中,你可以使用pip工具执行以下命令: ```bash pip install executor==21.1 ``` 安装完成后,你就可以在Python代码中导入并使用executor库了:...

    掌握并发的钥匙:Java Executor框架深度解析

    通过使用Executor框架,开发者可以更高效地管理并发任务,减少资源消耗,提高程序性能。此外,该框架还提供了一些高级功能,如任务调度,进一步增强了其灵活性。对于那些希望深入学习并发编程的开发者来说,掌握...

    Java并发编程利器:Executor框架深度解析与应用实践

    在现代Java应用开发中,多线程并发编程已成为提升...通过恰当地使用Executor框架,开发者可以编写出更加高效、稳定且易于维护的并发应用程序。掌握这一框架的原理和应用,对于每一个Java程序员来说都是非常有价值的技能

    针对于Executor框架,Java API,线程共享数据

    下面将详细介绍使用Executor框架的主要好处: - **简化线程管理**:Executor框架简化了线程的创建和管理过程。开发者无需关心底层的线程细节,只需关注任务的提交和执行即可。这极大地降低了多线程编程的难度。 - *...

    java并发编程:Executor、Executors、ExecutorService.docx

    传统的创建线程方式是通过`new Thread(new RunnableTask()).start()`,但使用Executor,可以通过`executor.execute(new RunnableTask())`异步执行任务,简化了代码并提高了可维护性。 2. ExecutorService: ...

    Java Executor 框架的实例详解

    Executor 框架的实例详解可以帮助开发者更好地理解和使用 Executor 框架,以下是 Java Executor 框架的实例详解的相关知识点: 一、Executor 框架的介绍 Executor 框架是 Java 中一个高级的并发编程模型,提供了一...

    apache zookeeper使用方法实例详解

    在 ZooKeeper 的 Java API 中,开发人员可以使用 Executor 类来维护与服务器端的连接,DataMonitor 类来监视 Znode 节点的数据。Executor 类包括 ZooKeeper 对象和 DataMonitor 对象,负责维护 ZooKeeper 连接,监视...

    Java中的Runnable接口最全讲义

    4.2 使用Executor框架启动线程池 5. 传递参数给线程: 5.1 使用构造方法传递参数 5.2 使用类成员变量传递参数 6. 线程同步: 6.1 线程安全性概述 6.2 使用同步方法 6.3 使用同步块 6.4 使用Lock和Condition 6.5 使用...

    spark:Executor分配详解

    观察CPU的使用率可以帮助调整Executor数量,以达到资源使用的最优化。 ##### 2.2 Executor数量的确定 - **默认配置**:默认情况下,每个Worker节点分配一个Executor。但可以通过配置文件或者代码动态设置每台机器...

    Executor 2.1 Pre-Release 11

    在使用时,用户应确保他们的系统满足Executor的最低硬件和软件要求,包括足够的内存、硬盘空间以及兼容的操作系统版本。 在实际操作中,用户可能需要将Mac应用程序的软盘映像文件或DMG文件加载到Executor中,以启动...

    重新编译好的contain-executor文件,指向/etc/hadoop/container-executor.cfg

    hadoop版本3.2.1 hadoop自带的Container-executor在配置yarn-kerberos时存在问题,...使用方法: 1 替换/$HADOOP_HOME/bin/下的container-executor 2 创建/etc/hadoop目录,并将container-executor.cfg放在该目录下即可

    Executor

    Executor是一款实用软件,专为提升Windows操作系统的使用体验而设计。这款工具的目的是优化和个性化用户的日常计算体验,使得各种任务执行更为流畅、快捷。Executor的主要功能集中在快速启动、自定义快捷方式以及对...

    重新编译的Container-executor 目录文件路径/etc/container-executor.cfg

    hadoop自带的Container-executor在配置yarn-kerberos时存在问题,这边给出编译后的Container-executor,默认加载配置文件路径/etc/container-executor.cfg,大家不用再重新编译了

    Executor-超好用的快捷启动软件

    在IT领域,这样的工具被广泛使用,尤其是对于经常需要频繁切换和执行各种任务的用户来说,Executor成为了他们桌面环境中的得力助手。 Executor的特点在于其高度的自定义性。用户可以根据自己的需求自由设定启动名称...

    Android Executor线程池

    本文将深入探讨`Android Executor`线程池的工作原理、优势以及如何在实际开发中使用。 一、`Executor`线程池简介 `Executor`框架是Java并发编程的重要组成部分,由`java.util.concurrent`包提供。它提供了一种更加...

    Java线程创建的四种方式

    Java线程是并发编程的基础,它...对于大型项目,推荐使用Executor框架来提高代码的可维护性和性能。在进行多线程编程时,还需要注意线程安全问题,如同步机制、锁的使用以及避免死锁等问题,确保程序的正确性和稳定性。

    Java中Executor接口用法总结

    Java中的Executor接口是Java并发编程的核心组件之一,它位于java.util.concurrent包中,为执行异步任务提供了一种统一的框架。Executor接口定义了一个...理解并熟练使用Executor,可以极大地提高Java并发编程的质量。

    顶层接口Executors详解

    可以将此种模式分为两层,在上层,Java多线程程序通常把应用程序分解为若干任务,然后使用用户级的调度器(Executor框架)讲这些任务映射为固定数量的线程;在底层,操作系统内核将这些线程映射到硬件处理器上。 3....

Global site tag (gtag.js) - Google Analytics