【java并发编程艺术学习】(二)第一章 java并发编程的挑战

章节介绍

主要介绍并发编程时间中可能遇到的问题,以及如何解决。

 主要问题

  1、上下文切换问题

    时间片是cpu分配给每个线程的时间,时间片非常短。

    cpu通过时间片分配算法来循环执行任务,当前任务执行一个时间片之后会切换到下一个任务。但是在切换之前会保存上一个任务的状态,以便再切换到这个任务时候,能够加载这个任务的状态。所以任务从保存再到加载的过程就是一次上下文切换。类似于读英文书时,遇到不懂的单词,记下读到的行数,翻出词典查询,查询完成后再翻到需要阅读的地方进行读取似的。

    举例说明 多线程程序不一定是最快的。

    1.1 代码示例

    

 1 package com.zhengze.test;
 2 
 3 public class Test1 {
 4 
 5     private static final long count = 10L;
 6     
 7     /**
 8      * 并行
 9      * @throws InterruptedException
10      */
11     public static void concurrency() throws InterruptedException {
12         long start = System.currentTimeMillis();
13         Thread thread = new Thread(new Runnable() {
14             
15             @Override
16             public void run() {
17                 // TODO Auto-generated method stub
18                 int a = 0;
19                 for(long i =0;i<count;i++){
20                     a +=5;
21                 }
22             }
23         });
24         thread.start();
25         int b = 0;
26         for(long i = 0; i<count ;i++){
27             b--;
28         }
29         long time = System.currentTimeMillis() - start;
30         thread.join();//TODO 这个方法是做什么的?
31         
32         System.out.println("时间:"+time+"===========b:"+b);
33         
34     }
35     
36     /**
37      * 串行
38      */
39     public static void serial(){
40         long start = System.currentTimeMillis();
41         int a = 0;
42         for(long i = 0; i<count;i++){
43             a +=5;
44         }
45         int b = 0;
46         for(long i = 0; i<count;i++){
47             b --;
48         }
49         long time = System.currentTimeMillis() - start;
50         System.out.println("时间2:"+time +"------a:"+a+"=====b:"+b);
51         
52     }
53     /**
54      * 测试示例
55      * @param args
56      * @throws InterruptedException
57      */
58     public static void main(String[] args) throws InterruptedException {
59         concurrency();
60         serial();
61 
62     }
63 
64 }

代码示例,得出结论:多线程并不一定就比串行程序块!此处测试,数据量达到百万级别时候,多线程的速度会更好些。

具体,参照《java并发编程的艺术》中对应第一章节详细阅读。

    1.2 减少上下文切换的方法

      无锁并发编程、CAS算法、使用最少线程(比如任务很少,要避免创建不必要的线程来处理)、使用协程等。

      (备注:这里需要补充下 协程 的知识点。。。。

  2、死锁

    避免死锁的常见方法:

    1、避免一个线程同时获取多个锁;

    2、避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源;

    3、尝试使用定时锁,使用 lock.tryLock(timeout)来替代使用内部锁机制;

    4、对于数据库锁,加锁和解锁必须在用一个数据库连接里,否则会出现解锁失败的情况。

  3、资源(软硬件等)限制的挑战

    主要分为硬件资源限制和 软件资源限制:

    硬件资源限制:主要为宽带的上传/下载速度、磁盘的读写速度、cpu的处理速度等;

    软件资源限制:主要为数据库的连接数、socket的连接数等。

小节

 笔者强烈推荐使用JDK并发包中提供的并发容器和工具类来解决并发问题。

(正在系统的学习下这部分的。)

原文地址:https://www.cnblogs.com/zhengzeze/p/9769317.html