并发编程的挑战


观看《Java并发编程的艺术》所做笔记

并发编程的挑战

上下文切换

概念

上下文切换:线程间的切换

线程切换前需要保持该线程的状态,这样下次切换回来的时候可以再加载到这个线程的状态

并发编程并不一定快,因为创建线程和上下文切换线程都需要开销,所以在某些情况下,并发执行并不一定快过串行执行

如何减少上下文切换
  • 避免使用锁: 多线程竞争锁时,会引起上下文切换(比如当前线程没拿到锁,它就挂起该线程,切换)
  • CAS操作: CAS操作是非阻塞式同步,不会使用锁
  • 使用最少线程: 避免创建不需要的线程,避免大多数线程都在WAITING状态,使用时分配的时间片短,频繁的上下文切换
  • 协程: 单线程中多任务调度,多任务在单线程中切换

死锁

查看死锁发生位置

/**
 * @author Tc.l
 * @Date 2020/11/26
 * @Description:
 */
public class DeadLockTest {
    static String A = "A";
    static String B = "B";
    public static void main(String[] args) {
        new Thread(()->{
            synchronized (A){
                try {
                    TimeUnit.SECONDS.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                synchronized (B){
                    System.out.println("A");
                }
            }
        }).start();


        new Thread(()->{
            synchronized (B){
                synchronized (A){
                    System.out.println("BBBB");
                }
            }
        }).start();
    }
}

jps -l 查看进程号

jstack 进程号查看堆栈信息

可以看到发现Java死锁

D:\代码\Java并发编程的艺术>jps -l
10900 org.jetbrains.idea.maven.server.RemoteMavenServer
1108 1²̵ս.DeadLockTest
5336 sun.tools.jps.Jps
15852

D:\代码\Java并发编程的艺术>jstack 1108
2020-11-26 21:46:19
Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.191-b12 mixed mode):

"DestroyJavaVM" #14 prio=5 os_prio=0 tid=0x0000000003482800 nid=0x748 waiting on condition [0x0000000000000000]
   java.lang.Thread.State: RUNNABLE

"Thread-1" #13 prio=5 os_prio=0 tid=0x000000001d6bf800 nid=0x37bc waiting for monitor entry [0x000000001e06f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at 1²̵ս.DeadLockTest.lambda$main$1(DeadLockTest.java:31)
        - waiting to lock <0x00000007810cb208> (a java.lang.String)
        - locked <0x00000007810cb238> (a java.lang.String)
        at 1²̵??.DeadLockTest$$Lambda$2/1078694789.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)

"Thread-0" #12 prio=5 os_prio=0 tid=0x000000001d6be800 nid=0x3bd4 waiting for monitor entry [0x000000001df6f000]
   java.lang.Thread.State: BLOCKED (on object monitor)
        at 1²̵ս.DeadLockTest.lambda$main$0(DeadLockTest.java:22)
        - waiting to lock <0x00000007810cb238> (a java.lang.String)
        - locked <0x00000007810cb208> (a java.lang.String)
        at 1²̵ս.DeadLockTest$$Lambda$1/1324119927.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)

...

Found one Java-level deadlock:
=============================
"Thread-1":
  waiting to lock monitor 0x000000001a9a21e8 (object 0x00000007810cb208, a java.lang.String),
  which is held by "Thread-0"
"Thread-0":
  waiting to lock monitor 0x000000001a9a35d8 (object 0x00000007810cb238, a java.lang.String),
  which is held by "Thread-1"

Java stack information for the threads listed above:
===================================================
"Thread-1":
        at 1²̵ս.DeadLockTest.lambda$main$1(DeadLockTest.java:31)
        - waiting to lock <0x00000007810cb208> (a java.lang.String)
        - locked <0x00000007810cb238> (a java.lang.String)
        at 1²̵ս.DeadLockTest$$Lambda$2/1078694789.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)
"Thread-0":
        at 1²̵ս.DeadLockTest.lambda$main$0(DeadLockTest.java:22)
        - waiting to lock <0x00000007810cb238> (a java.lang.String)
        - locked <0x00000007810cb208> (a java.lang.String)
        at 1²̵ս.DeadLockTest$$Lambda$1/1324119927.run(Unknown Source)
        at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

避免死锁:

  1. 避免一个线程同时获取多个锁
  2. 避免一个线程在锁内同时获取多个资源
  3. 尝试使用定时锁
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值