并发编程学习之路(一)

并发编程的目的是为了让程序运行的更快(单核处理器也支持多线程),但是并不是启动的线程越多,程序运行的就越快。

并发编程面临的问题:

  1.上下文的切换。

    解决办法:

       1. 无锁并发并发编程。多线程竞争锁时,会引起上下文切换,所以多线程处理数据时,可以用一些办法来避免使用锁,如将数据的ID按照Hash算法取模分段,不同的线程处理不同段的数据。

       2. CAS算法。Java的Atomic包使用CAS算法来更新数据,而不需要加锁。

       3. 使用最少线程。避免创建不需要的线程,比如任务很少,但是创建了很多线程来处理,这样会造成大量线程都处于等待状态。

       4. 协程:在单线程里实现多任务的调度,并在单线程里维持多个任务间的切换。

     (来源:《java并发编程的艺术》)

  2.死锁的问题。

    解决办法:

      1.避免一个线程使用多个锁。

      2.尝试使用定时锁,给每把锁设定超时时间。

多线程不一定快!!!

 1 public class ThreadDemo {
 2 
 3     private static final long count = 10000000;
 4 
 5     public static void chuanxing() {
 6         long start = System.currentTimeMillis();
 7         int a = 0;
 8         for (int i = 0; i <= count; i++) {
 9             a += 5;
10         }
11         int b = 0;
12         for (int i = 0; i <= count; i++) {
13             b--;
14         }
15         long time = System.currentTimeMillis() - start;
16         System.out.println("chuanxing time:" + time);
17     }
18 
19 
20     public static void bingxing() {
21         try {
22             long start = System.currentTimeMillis();
23             Thread t1 = new Thread(new Runnable() {
24                 @Override
25                 public void run() {
26                     int a = 0;
27                     for (int i = 0; i <= count; i++) {
28                         a += 5;
29                     }
30                 }
31             });
32             t1.start();
33             int b = 0;
34             for (int i = 0; i <= count; i++) {
35                 b--;
36             }
37             long time = System.currentTimeMillis() - start;
38             System.out.println("bingxing time:" + time);
39         } catch (Exception e) {
40             System.out.println("Exception");
41         }
42 
43     }
44 
45     public static void main(String args[]) {
46         chuanxing();
47         bingxing();
48     }
49 }

当count =10000   串行耗时:2ms    并行耗时:3ms

当count =100000   串行耗时:4ms    并行耗时:3ms

当count =1000000   串行耗时:5ms    并行耗时:4ms

当count =10000000   串行耗时:11ms    并行耗时:7ms

当count =100000000    串行耗时:85ms    并行耗时:54ms

由此可见,当数量级为十万级以内的时候,串行的速度明显比并行的速度快。

死锁的问题:

  1. 什么是死锁?

    存在资源A,B   线程1获取到资源A的锁时,此时线程2获取到资源B的锁,此时线程1获取资源B的锁时,线程2获取资源A的锁时,发现资源A,B的锁还被线程1,线程2所持有,则在线程1获取资源B的锁时,线程2获取资源A的锁时发生了死锁。

演示发生死锁:

 1 import java.util.concurrent.TimeUnit;
 2 
 3 public class LockDemo {
 4 
 5     private static String A="a";
 6     private static String B="b";
 7 
 8     private void deadLock(){
 9         Thread t1=new Thread(new Runnable() {
10             @Override
11             public void run() {
12                 synchronized (A){
13                     try {
14                         TimeUnit.SECONDS.sleep(5);
15                     } catch (InterruptedException e) {
16                         e.printStackTrace();
17                     }
18                     synchronized (B){
19                         System.out.println("B");
20                     }
21                 }
22 
23 
24             }
25         });
26 
27         Thread t2=new Thread(new Runnable() {
28             @Override
29             public void run() {
30                 synchronized (B){
31                     try {
32                         TimeUnit.SECONDS.sleep(4);
33                     } catch (InterruptedException e) {
34                         e.printStackTrace();
35                     }
36                     synchronized (A){
37                         System.out.println("A");
38                     }
39                 }
40             }
41         });
42         t1.start();
43         t2.start();
44     }
45 
46     public static void main(String args[]){
47         new LockDemo().deadLock();
48     }
49 }

猜你喜欢

转载自www.cnblogs.com/fengyue0520/p/10402376.html
今日推荐