并发编程艺术-1

并发编程艺术-1_第1张图片

本篇文章主要简单地介绍了并发编程的目的,上下文切换带来的影响,以及死锁的检测,解决,常见的并发资源限制。

  1. 并发编程目的何在
    主要还是为了让程序运行
    (1) 多线程一定快吗?
    (2)多线程上下文切换
    (3)是什么?
    CPU 给每一个线程分配时间片来支持多线程执行,通过不断的切换,让我们感觉多个线程是同时进行的,当然如果这仅仅是一个CPU来说,那么就是并行了,如果是多个CPU,那么每个CPU都可以同时执行一个线程,就是并发了。当线程切换的时候,需要保留一下现场,比如说程序计数器,相应寄存器的值,以便下次切换回这个线程时,加载当时的上下文。

  2. 会带来什么问题:
    现场保留和恢复需要损耗时间

  3. 如何减少?
    可以使用无锁并发,使用CAS算法就可以实现无锁,减少线程的使用,根据实际情况创建响应的线程数目进行任务的执行,比如说如果是IO密集型,可以开启2*Number(CPU)个线程,如果是计算密集型,开启Number(CPU)+1个线程。

  4. 如何判断当前线程切换太过频繁。
    使用JStack 进行判断,检查一下是否处于waiting 中的线程很多。

  5. 死锁以及解决方案

通常检测命令和工具:jstack 或者 JVisualVM
示例展示:
package com.eric.thread;

public class Deadlock {

private static String A = "java";
private static String B = "php";

public static void main(String[] args) {
    simulateDeadLock();
    
}

public static void simulateDeadLock(){
    Thread one = new Thread(new Runnable(){

        @Override
        public void run() {
            
            synchronized(A){
                
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    System.out.println(e.getMessage());
                }
                
                synchronized(B){
                    System.out.println("Thread one");
                }
            }
        }
    });
    one.start();
    Thread two = new Thread(new Runnable(){

        @Override
        public void run() {
            synchronized(B){
                synchronized(A){
                    System.out.println("Thread Two");
                }
            }
        }
        
    });
    two.start();
}

}

并发编程艺术-1_第2张图片
deadlock.PNG

Found one Java-level deadlock:

"Thread-1":
waiting to lock monitor 0x0000000056fab5c8 (object 0x00000000d960c9b8, a java.lang.String),
which is held by "Thread-0"
"Thread-0":
waiting to lock monitor 0x0000000059dd1fa8 (object 0x00000000d960c988, a java.lang.String),
which is held by "Thread-1"

Java stack information for the threads listed above:

"Thread-1":
at com.eric.thread.Deadlock$2.run(Deadlock.java:41)
- waiting to lock <0x00000000d960c9b8> (a java.lang.String)
- locked <0x00000000d960c988> (a java.lang.String)
at java.lang.Thread.run(Thread.java:745)
"Thread-0":
at com.eric.thread.Deadlock$1.run(Deadlock.java:29)
- waiting to lock <0x00000000d960c988> (a java.lang.String)
- locked <0x00000000d960c9b8> (a java.lang.String)
at java.lang.Thread.run(Thread.java:745)

Found 1 deadlock.

  1. 如何解决:
    避免一个线程同时获得多个锁,尝试使用定时锁。

7.资源限制。
数据库连接池,网络带宽,磁盘IO, socket 连接数等等,根据实际情况设计并发。

你可能感兴趣的:(并发编程艺术-1)