java多线程使用学习笔记

来源:互联网 发布:网络中奖的诈骗短信 编辑:程序博客网 时间:2024/06/03 11:25

初学Java多线程,后续继续改进


一,Callable

Callable是类似于Runnable的接口,实现Callable接口的类和实现Runnable的类都是可被其他线程执行的任务

Callable和Runnable的区别如下:

1.Callable定义的方法是call,而Runnable定义的方法是run。

2.Callable的call方法可以有返回值,而Runnable的run方法不能有返回值。

3.Callable的call方法可抛出异常,而Runnable的run方法不能抛出异常。


二,Executor



A,几种不同的ExecutorService线程池对象:

1. newCachedThreadPool()  缓存型池子,先查看池中有没有以前建立的线程,如果有,就reuse.如果没有,就建一个新的线程加入池中,自增型

2. newFixedThreadPool(int var0)任意时间点,最多只能有固定数目的活动线程存在,此时如果有新的线程要建立,只能放在另外的队列中等待,直到当前的线程中某个线程终止直接被移出池子

3.SingleThreadExecutor()单例线程,任意时间池中只能有一个线程 


4.ScheduledThreadPool()这个池子里的线程可以按schedule依次delay执行,或周期执行

ScheduledExecutorService threadPool = Executors.newScheduledThreadPool(2);System.out.println("开始时间"+new Date());threadPool.schedule(new MyExecutor(),2,TimeUnit.SECONDS);threadPool.schedule(new MyExecutor(),4,TimeUnit.SECONDS);


B,ExecutorService接口常用方法:

1.void shutdown()

    这个方法会平滑地关闭ExecutorService,当我们调用这个方法时,ExecutorService停止接受任何新的任务且等待已经提交的任务执行完成(已经提交的任务会分两类:一类是已经在执行的,另一类是还没有开始执行的),当所有已经提交的任务执行完毕后将会关闭ExecutorService

ExecutorService service = Executors.newCachedThreadPool();service.submit(new MyExecutor());service.shutdown();

2.boolean isTerminated(int timeout,TimeUnit unit)/booleanisShutdown()

    这个方法有两个参数,一个是timeout即超时时间,另一个是unit即时间单位。这个方法会使线程等待timeout时长,当超过timeout时间后,会监测ExecutorService是否已经关闭,若关闭则返回true,否则返回false。一般情况下会和shutdown方法组合使用

ExecutorService executorService= Executors.newCachedThreadPool();executorService.submit(new MyExecutor());executorService.submit(new MyExecutor());executorService.submit(new MyExecutor());executorService.submit(new MyExecutor());executorService.shutdown();System.out.println(executorService.isTerminated()+”-----"+executorService.isShutdown());


3.List<Runnable>  shutdownNow()

    个方法会强制关闭ExecutorService,它将取消所有运行中的任务和在工作队列中等待的任务,这个方法返回一个List列表,列表中返回的是等待在工作队列中的任务

ExecutorService service = Executors.newFixedThreadPool(3);service.submit(new MyExecutor());service.submit(new MyExecutor());service.submit(new MyExecutor());service.submit(new MyExecutor());List<Runnable> runnables = service.shutdownNow();System.out.println("等待个数:"+runnables.size());

4.boolean awaitTermination(long timeout, TimeUnit unit)

   这个方法有两个参数,一个是timeout即超时时间,另一个是unit即时间单位。这个方法会使线程等待timeout时长,当超过timeout时间后,会监测ExecutorService是否已经关闭,若关闭则返回true,否则返回false。一般情况下会和shutdown方法组合使用

ExecutorService service = Executors.newCachedThreadPool();service.submit(new MyExecutor());service.submit(new MyExecutor());service.submit(new MyExecutor());service.submit(new MyExecutor());service.shutdown();try {    while (!service.awaitTermination(1, TimeUnit.SECONDS)) {        System.out.println(“线程池没有关闭”);}System.out.println(“线程池已经关闭");


三,Future

Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并检索计算的结果。FutureTask类是Future 的一个实现,并实现了Runnable,所以可通过Excutor(线程池) 来执行,也可传递给Thread对象执行,一般FutureTask多用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果


常用方法:

1.boolean cancel(boolean mayInterruptIfRunning)  试图取消对此任务的执行。如果任务已完成、或已取消,或者由于某些其他原因而无法取消,则此尝试将失败。当调用 cancel 时,如果调用成功,而此任务尚未启动,则此任务将永不运行。如果任务已经启动,则 mayInterruptIfRunning 参数确定是否应该以试图停止任务的方式来中断执行此任务的线程。此方法返回后,对 isDone() 的后续调用将始终返回 true。如果此方法返回 true,则对 isCancelled() 的后续调用将始终返回 true

2.boolean isCancelled():如果在任务正常完成前将其取消,则返回 true,如果cancel方法返回 true,则对 isCancelled() 的后续调用将始终返回 true

3.boolean isDone():如果任务已完成,则返回 true。 可能由于正常终止、异常或取消而完成,在所有这些情况中,此方法都将返回 true。 

4.V get()throws InterruptedException,ExecutionException:如有必要,等待计算完成,然后获取其结果。 

5.V get(long timeout,TimeUnit unit) throws InterruptedException,ExecutionException,TimeoutException:如有必要,最多等待为使计算完成所给定的时间之后,获取其结果(如果结果可用)

class PGPageModelWorker implements Callable<Integer> {private int shopId;public PGPageModelWorker(int shopId) {this.shopId = shopId;}@Overridepublic Integer call() throws Exception {Random rand = new Random();int sleep=rand.nextInt(2000) + 500;//Thread.sleep(sleep);int s = shopId + 1;System.out.println(shopId+"执行时间---" + sleep+"毫秒");return s;}}


class FutureTask2Test{    public static void main(String[] args) throws InterruptedException {        final ConcurrentHashMap<String, Integer> modelMap = new ConcurrentHashMap<String, Integer>();final List<Integer> data=Collections.synchronizedList(new ArrayList<Integer>());        ExecutorService executor = Executors.newCachedThreadPool();        final CountDownLatch countDownLatch = new CountDownLatch(10);//Long startdate=System.currentTimeMillis();for (int i = 0; i < 1000; i++) {            final int id = i;            executor.submit(new FutureTask<Integer>(new PGPageModelWorker(id)) {                @Override                protected void done() {                    try {                        modelMap.put("key" + id, get());data.add(get());                    } catch (Exception e) {                        modelMap.put("key" + id, 0);                    } finally {                        countDownLatch.countDown();                    }                }            });        }System.out.println("----做其他的事------");System.out.println("------做其他的事----");System.out.println("-----做其他的事-----");try {Thread.sleep(3000);System.out.println("睡三秒");} catch (InterruptedException e) {e.printStackTrace();}System.out.println("-----做其他的事-----");System.out.println("-----做其他的事-----");System.out.println("-----做其他的事-----");System.out.println("-----做其他的事-----");int timeout = 3000;        countDownLatch.await(timeout, TimeUnit.MILLISECONDS);// 超时时间Long enddate=System.currentTimeMillis();System.out.println("执行时间:"+(enddate-startdate));Iterator<String> iterator=modelMap.keySet().iterator();        while (iterator.hasNext()){            String key=iterator.next();            System.out.println(key+"-----"+modelMap.get(key));        }System.out.println("---list遍历--------");Long start1=System.currentTimeMillis();for(Integer d:data){System.out.println(d);}System.out.println("遍历时间:"+(System.currentTimeMillis()-start1));System.out.println("list.size:"+data.size());    }}

CountDownLatch

      它可以让某些任务完成以后再继续运行下面的内容,每个任务本身执行完毕后让计数器减一,直到计数器清零后,以下的内容才可以继续运行,否则将阻塞等待


CountDownLatch有以下基本方法:

1)await(),阻塞等待,直到计数器清零

2)await(int timeout, TimeUnit unit),使线程阻塞,除非被中断或者超过等待的最大时间

如果达到计数器清零,则await返回true,如果等待超过了最大的等待时间,则返回false

3)countDown(),计数器减一,当计数器清零时,await的线程被唤醒,线程继续执行

4)getCount (),获取当前计数器的大小


public static void main(String[] args) throws Exception{    final CountDownLatch cdOrder=new CountDownLatch(1);    final CountDownLatch cdAnswer=new CountDownLatch(3);    System.out.println("等待运动员入场---------------");    try {        ExecutorService executor= Executors.newCachedThreadPool();;        for (int i = 1; i < 4; i++) {            final int c=i;            executor.submit(new Runnable() {                @Override                public void run() {                    try {                        System.out.println("运动员"+c+"准备就绪");                        cdOrder.await();                        System.out.println("运动员"+c+"已经起跑");                        Random rand = new Random();                        Thread.sleep(rand.nextInt(2000) + 500);                        cdAnswer.countDown();                        System.out.println("运动员"+c+"已到终点");                        System.out.println("还剩"+cdAnswer.getCount()+"个运动员未到");                    } catch (Exception e) {                        System.out.println("runable problem i="+c);                        e.printStackTrace();                    }                }            });        }    } catch (Exception e) {        System.out.println("thread problem");        e.printStackTrace();    }    try {        Thread.sleep(1000);        System.out.println("裁判已发布号令-----------------");        cdOrder.countDown();        cdAnswer.await();        System.out.println("裁判宣布结果------------");    } catch (Exception e){        System.out.println("main problem");        e.printStackTrace();    }}


五,CompletionService

      将生产新的异步任务与使用已完成任务的结果分离开来的服务,生产者 submit 执行的任务。使用者 take 已完成的任务,并按照完成这些任务的顺序处理它们的结果


CompletionService有以下基本方法:

    Future<V> submit(Callable<V> task);

    Future<V> submit(Runnable task, V result);

    Future<V> take() throws InterruptedException;

    Future<V> poll();

    Future<V> poll(long timeout, TimeUnit unit) throws InterruptedException;


class completionService2{    public static void main(String[] args) {        ExecutorService executor = Executors.newCachedThreadPool();        CompletionService<Integer> completionServcie = new ExecutorCompletionService<Integer>(                executor);        completionServcie.submit(new Runnable() {            @Override            public void run() {                try {                    Thread.sleep(2000);                } catch (InterruptedException e) {                    e.printStackTrace();                }            }        },1);        try {            System.out.println(completionServcie.poll(2000, TimeUnit.MILLISECONDS).get());        } catch (InterruptedException e) {            e.printStackTrace();        } catch (ExecutionException e) {            e.printStackTrace();        }    }}








0 0
原创粉丝点击