java多线程使用学习笔记

初学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)/boolean isShutdown()

    这个方法有两个参数,一个是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;
	}

	@Override
	public 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值