zoukankan      html  css  js  c++  java
  • Java多线程

    1. synchronized同步锁

    2. concurrent--并发工具包

    //以下类都线程安全
    ConcurrentHashMap 
    LinkedBlockingQueue --线程安全的阻塞(继承BlockingQueue)队列,可以指定容量,也可以不指定,不指定则默认值最大Integer.MAX_VALUE,其中主要用到put和take方法 ,put方法在队列满的时候会阻塞直到有队列成员被消费,take方法在队列空的时候会阻塞,直到有队列成员被放进来。
    ConcurrentLinkedQueue -- 非阻塞队列,当queue为空时不阻塞,而是返回null,需要程序自己进行处理
    

    3. Excutor-线程池-优先-Runnable

    3.0 自定义线程池中线程名称

    执行run方法前设置线程的名称,这样jstack0看到的线程名就可以是自定义的
    

    3.0 实现类-实现Runnable的run方法

    public class LiftOff implements Runnable {
        private  int index ;
    
        LiftOff(int xx) {
            this.index = xx;
        }
    
        @Override
        public void run() {
            try {
                Thread.sleep(500);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
    		System.out.println("current thread: "+Thread.currentThread().getId()+ ",index:"+this.index);
        }
    }
    

    3.1 Excutor.newCatchedThreadPool-每次创建线程,少用

    为每个任务都创建一个线程。当前的main线程继续运行,在Executor中的所有任务完成之后尽快退出。

    ExecutorService exec = Executors.newCachedThreadPool();
    for (int i = 0; i < 10; i++) {
    	exec.execute(new LiftOff(i));
    }
    //shutdown()方法的调用可以防止新任务被提交给Executor。
    exec.shutdown();
    System.out.println("main finished!");
    
    //可看出结果是无序的
    main finished!
    main finished!
    current thread: 11,index:0
    current thread: 12,index:1
    current thread: 13,index:2
    current thread: 15,index:4
    current thread: 14,index:3
    current thread: 16,index:5
    current thread: 17,index:6
    current thread: 20,index:9
    current thread: 19,index:8
    current thread: 18,index:7
    

    3.2 Excutor.newFixedThreadPool-数量固定,线程池,复用-常用

    预先执行一次代价昂贵的线程分配,复用线程来执行所提交的任务

    ExecutorService exec = Executors.newFixedThreadPool(2);
    for (int i = 0; i < 3; i++) {
    	exec.execute(new LiftOff(i));
    }
    //shutdown()方法的调用可以防止新任务被提交给Executor。
    exec.shutdown();
    System.out.println("main finished!");
    
    //可看出只使用了两个线程执行任务
    main finished!
    current thread: 12,index:1
    current thread: 11,index:0
    current thread: 11,index:3
    current thread: 12,index:2
    current thread: 11,index:4
    current thread: 12,index:5
    current thread: 11,index:6
    current thread: 12,index:7
    current thread: 11,index:8
    current thread: 12,index:9
    

    3.3 Executor.newSingleThreadExecutor-单线程按序执行

    数量1的newFixedThreadPool,多个任务排队执行.如多个线程都需要使用文件系统,可免去同步的操作

    ExecutorService exec = Executors.newSingleThreadExecutor();
    for (int i = 0; i < 5; i++) {
    	exec.execute(new LiftOff(i));
    }
    //shutdown()方法的调用可以防止新任务被提交给Executor。
    exec.shutdown();
    System.out.println("main finished!");
    
    //可看出是按序执行
    main finished!
    current thread: 11,index:0
    current thread: 11,index:1
    current thread: 11,index:2
    current thread: 11,index:3
    current thread: 11,index:4
    

    3.4 Executor.newScheduledThreadPool 定时任务-线程池

    public class LiftOff implements Runnable {
        @Override
        public void run() {
            try {
                Thread.sleep(2000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("Current thread:"+Thread.currentThread().getId()+", CurrentTime:"+new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E").format(new Date()));
        }
    }
    
    ScheduledExecutorService exec = Executors.newScheduledThreadPool(2);
    for (int i = 0; i < 5; i++) {
    	//exec.execute(new LiftOff(i));
    	exec.schedule(new LiftOff(i),3, TimeUnit.SECONDS);
    }
    //shutdown()方法的调用可以防止新任务被提交给Executor。
    exec.shutdown();
    System.out.println("Current Time:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss E").format(new Date()));
    System.out.println("main finished!");
    
    //执行结果
    Current Time:2017-08-04 14:18:42 星期五
    main finished!
    Current thread:11, CurrentTime:2017-08-04 14:18:47 星期五
    Current thread:12, CurrentTime:2017-08-04 14:18:47 星期五
    Current thread:12, CurrentTime:2017-08-04 14:18:49 星期五
    Current thread:11, CurrentTime:2017-08-04 14:18:49 星期五
    Current thread:12, CurrentTime:2017-08-04 14:18:51 星期五
    

    4. 分支/合并(Fork/Join)框架

    //原理
    使用“分而治之”算法。其思路是将算法要处理的数据空间拆成较小的独立块,这是“映射”阶段。一旦块集处理完毕之后,就可以将部分结果收集起来形成最终结果,这是“归约”阶段。
    一个例子:计算一个大型整数数组的总和。可以将数组划分为较小的部分,并发线程对这些部分计算部分和。然后部分相加,计算总和。此算法在多核架构上可看到明显的性能提升。
    //描述
    1.fork()	允许执行计划ForkJoinTask一步执行。这允许从现有的ForkJoinTask启动新的ForkJoinTask。
    2.join()	允许ForkJoinTask等待另一个ForkJoinTask完成。
    RecursiveAction	表示不产生返回值的执行。
    RecursiveTask	常用,产生返回值。
  • 相关阅读:
    oracle sql日期比较:
    vs 2008 过期问题
    silverlight带有复选框的列
    SQL 把一张表虚拟成两张表
    timeupdown
    ChildWindow 父窗体交互
    Debian CentOS修改时区
    如何优雅地使用命令行设置windows文件关联
    sql复制表结构,复制表内容语句
    VC6.0 中 添加/取消 块注释的Macro代码
  • 原文地址:https://www.cnblogs.com/Desneo/p/7227588.html
Copyright © 2011-2022 走看看