文档章节

Java挂起线程

trayvon
 trayvon
发布于 2017/05/03 19:27
字数 649
阅读 32
收藏 0

不优雅的suspend

import java.util.concurrent.TimeUnit;

public class SuspendTest {
    
    static Object lock = new Object();
    
    @SuppressWarnings("deprecation")
    public static void main(String[] args) {
        Suspend s1 = new Suspend();
        Suspend s2 = new Suspend();
        s1.start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        s1.resume();
        s2.start();
        s2.resume();
    }
    
    static class Suspend extends Thread{
        @SuppressWarnings("deprecation")
        @Override
        public void run() {
            synchronized(lock){
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                Thread.currentThread().suspend();
            }
        }
    }

}

上面的例子的一般情况s1是可以执行完成的,是因为先执行了suspend,后执行resume,而s2就被挂死了,因为s2先执行了resume,后执行的suspend。

下面是挂死之后上的堆栈信息:

"Thread-1" prio=6 tid=0x000000000c7bf000 nid=0x15a4 runnable [0x000000000d21e000]
   java.lang.Thread.State: RUNNABLE
    at java.lang.Thread.suspend0(Native Method)
    at java.lang.Thread.suspend(Unknown Source)
    at cn.d.concurrent.SuspendTest$Suspend.run(SuspendTest.java:34)
    - locked <0x00000007d5e99f78> (a java.lang.Object)

从上面的堆栈信息分析可以知道被挂死的s2的线程状态是RUNNABLE,并且没有释放它锁占用的锁0x00000007d5e99f78。

上面被挂死的原因有一部分是刻意为之,但是在多线程调度不确定的情况下不刻意,使用suspend也很容易找出挂死,因为它的确有一些问题,所以才会被废弃。

suspend的代替方法

需要用到suspend的地方基本都刻意替换为wait,notify模式,如果你想要简单实现,刻意考虑JUC提供的工具LockSupport。下面的例子使用LockSupport工具替换上面例子的suspend和resume方法。

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.LockSupport;

public class SuspendTest2 {
    
    static Object lock = new Object();
    
    public static void main(String[] args) {
        Suspend s1 = new Suspend();
        Suspend s2 = new Suspend();
        s1.start();
        try {
            TimeUnit.SECONDS.sleep(1);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        LockSupport.unpark(s1);
        s2.start();
        LockSupport.unpark(s2);
        
    }
    
    static class Suspend extends Thread{
        @Override
        public void run() {
            synchronized(lock){
                try {
                    TimeUnit.MILLISECONDS.sleep(500);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                LockSupport.park();
            }
        }
    }

}

使用LockSupport工具的静态方法轻松加愉快的就解决了suspend和resume带来的问题。

总结

  1. 尽量不要使用suspend来挂起线程
  2. 考虑使用wait,notify模式来代替suspend
  3. 考虑使用JUC的LockSupport来代替suspend

© 著作权归作者所有

下一篇: Java多线程stop
trayvon
粉丝 16
博文 132
码字总数 197492
作品 1
程序员
私信 提问
java 调用exe程序挂起

最近在做一个java工具,java多线程执行bat文件, 每个bat文件又会调用两个exe文件(a.exe | b.exe)。 每一个线程单独执行一个bat文件。线程执行bat文件。 因为数据量很大,活执行很多次bat...

ifso
2015/07/23
506
1
Java并发编程(一)Thread详解

一、概述 在开始学习Thread之前,我们先来了解一下 线程和进程之间的关系: 线程(Thread)是进程的一个实体,是CPU调度和分派的基本单位。 线程不能够独立执行,必须依存在应用程序中,由应用...

王磊的博客
2018/10/09
0
0
Java轻量级锁原理详解(Lightweight Locking)

大家知道,Java的多线程安全是基于Lock机制实现的,而Lock的性能往往不如人意。 原因是,monitorenter与monitorexit这两个控制多线程同步的bytecode原语,是JVM依赖操作系统互斥(mutex)来实现...

serenity
2015/08/11
0
0
sun.misc.Unsafe的各种神技Unsafe

sun.misc.Unsafe包 Unsafe类在jdk 源码的多个类中用到,这个类的提供了一些绕开JVM的更底层功能,基于它的实现可以提高效率。但是,它是一把双刃剑:正如它的名字所预示的那样,它是Unsafe的...

HJCui
2018/05/24
0
0
CAS原理 Java SE1.6中的Synchronized

在JDK 5之前Java语言是靠synchronized关键字保证同步的,这会导致有锁(后面的章节还会谈到锁)。 锁机制存在以下问题: (1)在多线程竞争下,加锁、释放锁会导致比较多的上下文切换和调度延...

指尖的舞者
2014/04/23
0
0

没有更多内容

加载失败,请刷新页面

加载更多

Spark Streaming的优化之路——从Receiver到Direct模式

          作者:个推数据研发工程师 学长 1 业务背景 随着大数据的快速发展,业务场景越来越复杂,离线式的批处理框架MapReduce已经不能满足业务,大量的场景需要实时的数据处理结果来...

个推
45分钟前
2
0
壮丽70年·奋斗新时代|蒸妙集团熏蒸中会阴熏蒸的神奇好处

聚结相合之处为会。会阴居两阴间,为督、任、冲三脉的起点,三脉背出两阴之间,会聚阴部,因名会阴。会阴,经穴名。出《针灸甲乙经》。会阴别名屏翳、下极、金门。属任脉。在会阴部,男性当阴...

公益传承
54分钟前
2
0
pentaho-kettle-8.2.0.0-R源码开发环境搭建

1.从Kettle官网下载源码,本文使用的是pentaho-kettle-8.2.0.0-R 下载地址:https://codeload.github.com/pentaho/pentaho-kettle/zip/8.2.0.0-R 2.打开eclipse,选择一个新的工作空间,然后设...

gq_2010
今天
1
0
lua web快速开发指南(7) - 高效的接口调用 - httpc库

httpc库基于cf框架都内部实现的socket编写的http client库. httpc库内置SSL支持, 在不使用代理的情况下就可以请求第三方接口. httpc支持header、args、body、timeout请求设置, 完美支持各种h...

水果糖的小铺子
今天
5
0
通过四道常问面试题,带你了解什么是数据库分库分表

编者语:为了避免被误解为:「手里有把锤子,看什么都是钉子!」,说明一下不是什么业务都适合分布式数据库,更不是用了分布式数据库性能就一定能得到扩展。 其次:本文为纯干货,建议先转发...

老道士
今天
8
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部