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	常用,产生返回值。
posted @ 2017-07-24 10:23  Desneo  阅读(210)  评论(0编辑  收藏  举报