并发编程艺术-1

作者: e86dab508bc1 | 来源:发表于2018-04-13 23:29 被阅读0次

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

    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();
    }
    

    }

    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

        本文链接:https://www.haomeiwen.com/subject/trqhhftx.html