首页 > 编程知识 正文

epoll实现原理,executors四种线程池

时间:2023-05-06 19:06:21 阅读:42548 作者:1646

在Java5中,Java线程的类库得到了极大的扩展。 其中,线程池是Java5的新特点之一,除了线程池之外,还有很多与多线程相关的内容,对多线程编程非常有用。 为了编写高效稳定可靠的多线程程序,线程部分的新内容尤为重要。

有关Java5线程新特征的内容都在java.util.concurrent下,其中包含许多接口和类,这是一个很难熟悉这部分API特征的学习过程。 目前,有关这方面的资料和书籍都很少,大所属介绍线程的书籍只停留在java5以前的知识水平。

当然,新的特点在编写多线程程序中并不是必须的,直到java5为止,都可以编写出通用的优秀的多线程程序。 只是代价不同。

线程池的基本思想也是池的形象。 打开包含大量(未死)线程的内存空间,池管理器将处理池中线程的运行时间表。 通过从池中提取一个线程任务(如果有),并在运行完成时池中池线程对象,可以避免重复创建线程对象带来的性能开销,从而节省系统资源。

在Java5之前,实现线程池是一件相当困难的事情,但现在Java5已经实现了一切。 只要按照提供的API使用,就可以享受线程池的便利。

Java5的线程池有很多。 具体来说是固定尺寸的线程池、可变尺寸连接池。

在使用线程池之前,必须知道如何创建线程池。 在Java5中,您必须知道java.util.concurrent.Executors类的API,该类提供了创建大量连接池的静态方法。

介绍如何创建线程和管理线程池。 在Java语言中,最简单的线程类似于以下代码:

Runnable runnable=new Runnable (

公共void run (}

system.out.println('run );

}

}

可以从以下代码行启动此线程:

newthread(runnable ).start );

这已经是一个很简单的例子,但是如果有很多需要长时间运行的任务同时运行,等待所有这些线程运行,然后试图获得返回值,这就有点困难了。 但是,Java已经有了解决方案。 那是执行程序。 可以在简单的类中创建线程池和线程工厂。 线程池是使用类ExecutorService的实例表示的,可以使用ExecutorService发送任务并执行计划的运行。 列出可以从Executors类创建的几种线程池类型。

http://www.Sina.com/: singlethreadexecutor :只有一个线程线程池,因此所有提交的任务都将按顺序执行。

代码:单线程线程池

说明:创建大小为1的固定线程池,同时只运行一个任务(task ),所有其他(task )任务)都在LinkedBlockingQueue中排队等待运行。

3358 www.Sina.com//cached thread pool 3360线程池中有许多线程需要同时运行,旧的可用线程由新任务重新运行。 如果线程未运行超过60秒,它将退出并从池中删除。

代码:Executors.newSingleThreadExecutor()

说明:使用时,放在线程池中的task任务将复用线程或启动新线程来执行。 注:如果启动的线程数超过最大整数,则会抛出RejectedExecutionException异常,启动后线程的生存时间为1分钟。

3358 www.Sina.com/fixed thread pool :具有固定线程数的线程池,如果没有任务执行,线程将继续等待

代码:缓存线程池

说明:创建固定大小(nThreads,大小不超过int最大值)的线程池。 缓冲区任务队列为LinkedBlockingQueue,大小为整数的最大值。使用此线程池,可以在同时执行的任务数超过接收线程池的大小值后将其置于LinkedBlockingQueue中如果部署到LinkedBlockingQueue的任务超过了整数的最大数目,则抛出RejectedExecutionException。 (newFixedThreadPool参数指定可以执行的线程的最大数量。 如果添加的线程数超过此数,则不执行。 其次,参与线程池的线程处于主机状态,线程的执行不受参与顺序的影响。 )

3358 www.Sina.com/scheduled thread pool :调度即将执行的任务的线程池

代码:Executors.newCachedThreadPool()

rs.newScheduledThreadPool()


单线程周期性线程池:Single Thread Scheduled Pool : 只有一个线程,用来调度执行将来的任务,代码:
Executors.newSingleThreadScheduledExecutor()
说明:线程keepAliveTime为0,缓存任务的队列为DelayedWorkQueue,注意不要超过整型的最大值。


一旦你创建了一个线程池,你就可以往池中通过不同的方法提交执行任务,可提交 Runnable 或者 Callable 到线程池中,该方法返回一个 Future 实例表示任务的状态,如果你提交一个 Runnable ,那么如果任务完成后 Future 对象返回 null。
例如,你编写下面的 Callable:


private final class StringTask extends Callable<String>{
   public String call(){
      //Long operations
 
      return "Run";
   }
}
如果你想使用4个线程来执行这个任务10次,那么代码如下:


ExecutorService pool = Executors.newFixedThreadPool(4);
 
for(int i = 0; i < 10; i++){
   pool.submit(new StringTask());
}
但你必须手工的关闭线程池来结束所有池中的线程:

pool.shutdown();
如果你不这么做,JVM 并不会去关闭这些线程;另外你可以使用 shutdownNow() 的方法来强制关闭线程池,那么执行中的线程也会被中断,所有尚未被执行的任务也将不会再执行。但这个例子中,你无法获取任务的执行状态,因此我们需要借助 Future 对象:


ExecutorService pool = Executors.newFixedThreadPool(4);
 
List<Future<String>> futures = new ArrayList<Future<String>>(10);
 
for(int i = 0; i < 10; i++){
   futures.add(pool.submit(new StringTask()));
}
 
for(Future<String> future : futures){
   String result = future.get();
 
   //Compute the result
}
 
pool.shutdown();
 


不过这段代码稍微有点复杂,而且有不足的地方。如果第一个任务耗费非常长的时间来执行,然后其他的任务都早于它结束,那么当前线程就无法在第一个任务结束之前获得执行结果,但是别着急,Java 为你提供了解决方案——CompletionService。一个 CompletionService 就是一个服务,用以简化等待任务的执行结果,实现的类是 ExecutorCompletionService,该类基于 ExecutorService,因此我们可试试下面的代码:


ExecutorService threadPool = Executors.newFixedThreadPool(4);
CompletionService<String> pool = new ExecutorCompletionService<String>(threadPool);
 
for(int i = 0; i < 10; i++){
   pool.submit(new StringTask());
}
 
for(int i = 0; i < 10; i++){
   String result = pool.take().get();
 
   //Compute the result
}
 
threadPool.shutdown();
通过这段代码,我们可以根据执行结束的顺序获取对应的结果,而无需维护一个 Future 对象的集合。这就是本文的全部,通过 Java 为我们提供的各种工具,可以方便的进行多任务的编程,通过使用 Executors、ExecutorService 以及 CompletionService 等工具类,我们可以创建复杂的并行任务执行算法,而且可以轻松改变线程数。


自定义线程池

public class TestThread {
    public static void main(String args[]){
          //创建等待队列 
        BlockingQueue<Runnable> bqueue = new ArrayBlockingQueue<Runnable>(20); 
        //创建一个单线程执行程序,它可安排在给定延迟后运行命令或者定期地执行。 
        ThreadPoolExecutor pool = new ThreadPoolExecutor(2,3,2,TimeUnit.MILLISECONDS,bqueue); 


        //创建实现了runnable接口的对象
        Thread t1 = new MyThread();
        Thread t2 = new MyThread();
        Thread t3 = new MyThread();
        Thread t4 = new MyThread();
        Thread t5 = new MyThread();
        //将线程放入池中进行执行
        pool.execute(t1);
        pool.execute(t2);
        pool.execute(t3);
        pool.execute(t4);
        pool.execute(t5);
        //关闭线程池
        pool.shutdown();
    }
}
 class MyThread extends Thread{
     
     @Override
     public void run(){
         System.out.println(Thread.currentThread().getName()+" is running...");
    try { 
         Thread.sleep(100L); 
     } catch (InterruptedException e) { 
             e.printStackTrace(); 
     } 
     }
 }

原文出处:https://blog.csdn.net/aimiaochun1/article/details/73604788

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。