并发编程的目的是为了让程序运行的更快(单核处理器也支持多线程),但是并不是启动的线程越多,程序运行的就越快。
并发编程面临的问题:
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 }
原文:https://www.cnblogs.com/fengyue0520/p/10402376.html