发布于 2015-12-22 19:56:59 | 51 次阅读 | 评论: 0 | 来源: PHPERZ

这里有新鲜出炉的Java设计模式,程序狗速度看过来!

Java程序设计语言

java 是一种可以撰写跨平台应用软件的面向对象的程序设计语言,是由Sun Microsystems公司于1995年5月推出的Java程序设计语言和Java平台(即JavaEE(j2ee), JavaME(j2me), JavaSE(j2se))的总称。


为什么需要执行框架呢?
使用一般的new方法来创建线程有什么问题呢?一般的new线程的方式一般要给出一个实现了Runnable接口的执行类,在其中重写run()方法,然后再在将这个执行类的对象传给线程以完成初始化,这个过程中线程的定义和执行过程其实是杂糅在一起了,而且每次new一个新的线程出来在资源上很有可能会产生不必要的消耗,因此我们通过多线程执行框架来解决这两个问题,其一可以分离线程的定义和执行过程,其二可以通过线程池来动态地管理线程以减小不必要的资源开销。

线程执行框架启动线程
将要多线程执行的任务封装为一个Runnable对象,将其传给一个执行框架Executor对象, Executor从线程池中选择线程执行工作任务。

创建多线程框架对象调用线程执行任务
我们通常通过Executors类的一些静态方法来实例化Executor或ThreadPoolExecutor对象:

比如Executor对象来执行:

public class ThreadTest {
    public static void main(String[] args) {
        Executor executor = Executors.newSingleThreadExecutor();
        executor.execute(new MyRunnable());
    }
}

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("running");
    }
}

比如线程池的Executor对象来执行:

public class ThreadTest {
    public static void main(String[] args) {
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors
                .newFixedThreadPool(3);
        executor.execute(new MyRunnable());
    }
}

class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("running");
    }
}
  • Executors. newSingleThreadExecutor():一 个线程死掉后,自动重新创建后一个新的线程,所以没有线程池的概念,不能被ThreadPoolExecutor接收;

  • Executors. newFixedThreadPool():固定数目的线程池;

  • Executors. newCachedThreadPool():动态地增加和减少线程数;

多线程框架对象调用线程执行任务取回结果
实现了Runnable接口的执行类虽然可以在run()方法里写入执行体,但是无法返回结果值,因为run()方法是void型的,而Callable接口解决了这个问题,在继承了Callable接口的执行类中重写call()方法可以设置返回值,当Executor对象使用submit()函数提交执行类的时候会由线程池里的线程来运行,运行得到的返回值可以使用Future<V>接口来接,取得的返回值类型由V决定,Future<V>接口表示可能会得到的返回值,但是有可能报异常,因此要抛出这些异常,然后可以取得这些返回值。

public class ThreadTest {
    public static void main(String[] args) throws InterruptedException,
            ExecutionException {
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors
                .newCachedThreadPool();
        MyCallable myCallable = new MyCallable(2);
        Future<Integer> result = executor.submit(myCallable);
        System.out.println(result.get());
    }
}

class MyCallable implements Callable<Integer> {
    private int num;

    public MyCallable(int num) {
        this.num = num;
    }

    @Override
    public Integer call() throws Exception {
        return num * 2;
    }
}

多线程框架对象调用线程执行任务完成第一个还是全部完成就取回结果
使用submit()函数取回的结果不能控制任务是完成第一个还是全部完成就取回结果,然而使用invokeAny()和invokeAll()函数即可获得这样的效果,将执行体对象放入集合中传入这两个函数,前者可以在完成任务的多线程有一个(第一个)完成时就返回结果,因此结果类型是单结果,而后者则需要等待所有执行任务的线程都执行完毕才返回结果,因此结果仍是集合。

1.invokeAny():

public class ThreadTest {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors.newFixedThreadPool(5);
List<MyCallable> callables = new ArrayList<>();
for(int i=0;i<10;i++){
MyCallable myCallable = new MyCallable(i);
callables.add(myCallable);
}
Integer res = executor.invokeAny(callables);
System.out.println(res);

}
}

class MyCallable implements Callable<Integer> {
    private int num;

    public MyCallable(int num) {
        this.num = num;
    }

    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName() + " is running");
        return num * 2;
    }
}

2.invokeAll():

public class ThreadTest {
    public static void main(String[] args) throws InterruptedException,
            ExecutionException {
        ThreadPoolExecutor executor = (ThreadPoolExecutor) Executors
                .newFixedThreadPool(5);
        List<MyCallable> callables = new ArrayList<MyCallable>();
        for (int i = 0; i < 10; i++) {
            MyCallable myCallable = new MyCallable(i);
            callables.add(myCallable);
        }
        List<Future<Integer>> res = executor.invokeAll(callables);
        for (Future<Integer> future : res) {
            System.out.println(future.get());
        }
    }
}

class MyCallable implements Callable<Integer> {
    private int num;

    public MyCallable(int num) {
        this.num = num;
    }

    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName() + " is running");
        return num * 2;
    }
}

多线程框架对象执行定时任务
使用Executor的schedule()函数族来调度线程池中的线程来执行callable执行类对象中的call()定时任务:

public class ThreadTest {
    public static void main(String[] args) throws InterruptedException,
            ExecutionException {
        ScheduledExecutorService executorService = Executors
                .newScheduledThreadPool(2);
        MyCallable callable = new MyCallable(2);
        executorService.schedule(callable, 10, TimeUnit.SECONDS);
        executorService.shutdown();
    }
}

class MyCallable implements Callable<Integer> {
    private int num;

    public MyCallable(int num) {
        this.num = num;
    }

    @Override
    public Integer call() throws Exception {
        System.out.println(Thread.currentThread().getName() + " is running");
        return num * 2;
    }
}


相关阅读 :
Java多线程:Java多线程执行框架
Java多线程--让主线程等待所有子线程执行完毕在执行
Java并发编程示例(六):等待线程执行终止
Java中一个线程执行死循环有什么后果
Java 线程池框架
Java线程池框架核心代码解析
Java Web项目中Spring框架处理JSON格式数据的方法
Java中的异常测试框架JUnit使用上手指南
Java编程中使用XFire框架调用WebService程序接口
java打包成可执行的jar或者exe的详细步骤
java使用任务架构执行任务调度示例
分析java 中AspectJ切面执行两次的原因
最新网友评论  共有(0)条评论 发布评论 返回顶部
月排行榜

Copyright © 2007-2017 PHPERZ.COM All Rights Reserved   冀ICP备14009818号  版权声明  广告服务