精华内容
下载资源
问答
  • Java.lang.Thread的sleep()方法能使当前线程暂停运行一段时间(单位毫秒)。需要注意的是,sleep()方法的参数不能为负,否则会抛出IllegalArgumentException异常。除此之外,还有另一个方法sleep(long millis, int ...

    Java.lang.Thread的sleep()方法能使当前线程暂停运行一段时间(单位毫秒)。需要注意的是,sleep()方法的参数不能为负,否则会抛出IllegalArgumentException异常。

    除此之外,还有另一个方法sleep(long millis, int nanos),该方法可用于使当前线程暂停millis毫秒nanos纳秒。需要注意的是,参数nanos的取值范围为[0, 999999]。

    下面的代码演示如何用Thread.sleep()方法令主线程暂停执行2秒。

    ThreadSleep.java

    package com.journaldev.threads;

    public class ThreadSleep {

    public static void main(String[] args) throws InterruptedException {

    long start = System.currentTimeMillis();

    Thread.sleep(2000);

    System.out.println("Sleep time in ms = " + (System.currentTimeMillis()-start));

    }

    }

    如果你运行上述程序,你会发现最后打印出来的结果会比2000略多一些,这取决于线程休眠是如何实现的,以及操作系统定义的线程调度机制。

    线程休眠要点

    1. 线程休眠总是暂停当前线程

    2. 在被唤醒并开始执行前,线程休眠的实际时间取决于系统计时器和调度器。对比较清闲的系统来说,实际休眠的时间十分接近于指定的休眠时间,但对于繁忙的系统,两者之间的差距就较大。

    3. 线程休眠并不会丢失当前线程已获取的任何监视器和锁。

    4. 其他线程可以中断当前进程的休眠,但会抛出InterruptedException异常。

    线程休眠的工作原理

    Thread.sleep()与线程调度器交互,它将当前线程设置为等待一段时间的状态。一旦等待时间结束,线程状态就会被改为可运行(runnable),并开始等待CPU来执行后续的任务。因此,当前线程的实际休眠时间取决于线程调度器,而线程调度器则是由操作系统来进行管理的。

    0b1331709591d260c1c78e86d0c51c18.png

    展开全文
  • 一个疯狂的猜测是,某些值被缓存在处理器本地缓存中,当线程进入休眠状态时会被刷新,然后当线程唤醒时需要从主内存中检索该值,但这并不是那么快.然而,这并不能解释为什么颠倒订单会产生影响…… 我最初观察到这种行为...

    附加程序(见最后)在执行时产生以下输出:

    ..........

    with sleep time of 0ms

    times= [1, 1, 1, 0, 1, 1, 0, 1, 1, 0]

    average= 0.7

    ..........

    with sleep time of 2000ms

    times= [2, 2, 2, 2, 2, 1, 2, 2, 2, 2]

    average= 1.9

    在这两种情况下,执行完全相同的代码,即从程序开始时实例化的Random对象重复获取下一个值.首先执行的预热方法应该在实际测试开始之前触发任何类型的JIT otimization.

    任何人都可以解释这种差异的原因吗?到目前为止,我每次都能在我的机器上重复这个结果,这是在带有java 7的多核Windows系统上执行的.

    一个有趣的事情是,如果执行测试的顺序是相反的,也就是说,如果我们在没有延迟的循环之前运行具有延迟的循环,那么时序更相似(没有延迟循环实际上需要更长的时间) ):

    ..........

    with sleep time of 2000ms

    times= [2, 2, 2, 2, 2, 2, 2, 2, 2, 2]

    average= 2.0

    ..........

    with sleep time of 0ms

    times= [2, 3, 3, 2, 3, 3, 2, 3, 2, 3]

    average= 2.6

    尽管我可以告诉,在操作方法中没有创建任何对象,并且当通过分析器运行它时,似乎不会触发垃圾收集.一个疯狂的猜测是,某些值被缓存在处理器本地缓存中,当线程进入休眠状态时会被刷新,然后当线程唤醒时需要从主内存中检索该值,但这并不是那么快.然而,这并不能解释为什么颠倒订单会产生影响……

    我最初观察到这种行为的现实情况(这促使我编写这个示例测试类)是XML解组,我注意到,在快速连续中一个接一个地重复编组同一个文档所产生的时间比执行相同的更好的时间但是在调用unmarshal(通过睡眠或手动产生的延迟)之间有延迟.

    这是代码:

    import java.util.ArrayList;

    import java.util.List;

    import java.util.Random;

    public class Tester

    {

    public static void main(String[] args) throws InterruptedException

    {

    warmUp(10000);

    int numRepetitions = 10;

    runOperationInALoop(numRepetitions, 0);

    runOperationInALoop(numRepetitions, 2000);

    }

    private static void runOperationInALoop(int numRepetitions, int sleepTime) throws InterruptedException

    {

    List times = new ArrayList(numRepetitions);

    long totalDuration = 0;

    for(int i=0; i

    {

    Thread.sleep(sleepTime);

    long before = System.currentTimeMillis();

    someOperation();

    long duration = System.currentTimeMillis() - before;

    times.add(duration);

    totalDuration = totalDuration + duration;

    System.out.print(".");

    }

    System.out.println();

    double averageTimePerOperation = totalDuration/(double)numRepetitions;

    System.out.println("with sleep time of " + sleepTime + "ms");

    System.out.println(" times= " + times);

    System.out.println(" average= " + averageTimePerOperation);

    }

    private static void warmUp(int warmUpRepetitions)

    {

    for(int i=0; i

    {

    someOperation();

    }

    }

    public static int someInt;

    public static Random random = new Random(123456789L);

    private static void someOperation()

    {

    for(int j=0; j<50000; j++)

    {

    someInt = ((int)random.nextInt()*10) + 1;

    }

    }

    }

    展开全文
  • 自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。...

    1、简介sleep

    sleep方法属于Thread类中方法,是静态方法,只能控制当在前运行的线程。表示让一个线程进入睡眠状态,等待一定的时间之后,自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。但在sleep的过程中过程中有可能被其他对象调用它的interrupt(),产生InterruptedException异常,如果你的程序不捕获这个异常,线程就会异常终止,进入TERMINATED状态,如果你的程序捕获了这个异常,那么程序就会继续执行catch语句块(可能还有 finally语句块)以及以后的代码。

    sleep(long millis)

    在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)

    sleep(long millis, int nanos)

    在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行)

    2、运用场景

    执行其它任务的时候,想要每间隔多少秒执行一次给定任务,sleep就会用上。

    3、代码事例

    package com.xxx.util;

    import java.util.Date;

    /**

    * Created with IntelliJ IDEA.

    * Date: 15-3-27

    * Time: 上午8:51

    * To change this template use File | Settings | File Templates.

    */

    public class ThreadSleep implements Runnable {

    @Override

    public void run() {

    for(int i=0;i<15;i++){

    System.out.printf("startTime:%s\n",new Date());

    try {

    Thread.sleep(1000);

    } catch (InterruptedException e) {

    //线程中断在此处理

    System.out.println("The thread has bean interrupted");

    }

    }

    }

    }main类

    package com.xxx.util;

    import java.util.concurrent.TimeUnit;

    /**

    * Created with IntelliJ IDEA.

    * Date: 15-3-27

    * Time: 上午8:57

    * To change this template use File | Settings | File Templates.

    */

    public class ThreadSleepMain {

    public static void main(String[] args){

    ThreadSleep threadSleep = new ThreadSleep();

    Thread thread = new Thread(threadSleep);

    thread.start();

    try {

    TimeUnit.SECONDS.sleep(5);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    thread.interrupt();

    System.out.printf("%s:已调用interrupt()方法\n",thread.getName());

    System.out.printf("%s:主线程还在运行\n",Thread.currentThread().getName());

    }

    }运行结果:

    0818b9ca8b590ca3270a3433284dd417.png

    4、结论

    当调用sleep()方法后,线程会释放CPU并且不再继续执行任务,知道休眠时间过了才进入可运行状态。如果休眠中线程被中断,该方法会立即抛出InterruptedException异常,可进行异常处理,main线程还是继续运行不受影响。

    展开全文
  • 在几个月前上线的一个采集项目,构架是基于java + selenium + chromedriver + chrome实现的采集。至于为哈不直接用jsoup或httpclient实现采集功能,是因为很多被采集页面都是通过js来渲染内容的,所以必须用...

    在几个月前上线的一个采集项目,构架是基于java + selenium + chromedriver + chrome实现的采集。至于为哈不直接用jsoup或httpclient实现采集功能,是因为很多被采集页面都是通过js来渲染内容的,所以必须用webdriver+chrome来模拟真正的浏览器访问来采集。

    每隔一段时间就会出采集失败问题,出现的时间没有规律,可能两天出现一次,可能一星期出现一次,可能一个月出现一次....

    用linux top命令来查看服务器,会发现很多的chromedriver和chrome的进程

    用ps命令查看服务器

    ps -aux | grep chrome

    b3381d72505d5f739055162adf7ca2a3.png

    存在状态为Sl和Z的休眠进程和僵尸进程,启动时间都不是当天,根据系统本身业务逻辑,进程不会存在运行那么长时间的情况。而java进程则全部都能正常关闭,但java进程启动的chromedriver和chrome进程不一定能同时关闭,目前出现这种问题的原因未找到。

    最初想用命令把卡死的进程查出来批量杀掉

    ps -A -o stat,ppid,pid,cmd | grep -e '^[Zz]' | awk '{print $2}' | xargs kill -9 //杀死僵尸进程

    结果发现只能查杀Z状态的僵尸进程,Sl状态的进程,一部分是正常的,一部分是需要杀死的(启动时间为Nov07,Nov06的进程需要杀掉),至于哪些需要杀死,需要通过人工判断启动时间来确定是否需要杀掉进程。

    之前一直忙时,都是先通过ps命令把chromedriver和chrome相关进程查询出来,然后通过人工判断进程是否属于休眠状态,再手工kill杀掉进程。

    最近有空了,本着能程序解决,就绝不要人工维护,把之前的手工杀休眠进程操作程序化。一开始想直接通过java的Runtime.getRuntime().exec()代码调用linux命令操作的,不过在java常用类库中(https://www.21doc.net/java/awesomejava#processes),找到zt-exec库,可以简化命令行调用操作。

    程序化的代替人工维护实现定时清理休眠进程代码如下:

    import org.apache.log4j.Logger;

    import org.apache.log4j.RollingFileAppender;

    import org.zeroturnaround.exec.ProcessExecutor;

    import org.zeroturnaround.exec.stream.LogOutputStream;

    import java.util.ArrayList;

    import java.util.Enumeration;

    import java.util.List;

    import java.util.regex.Matcher;

    import java.util.regex.Pattern;

    public class ProcessKill {

    private static Logger log = Logger.getLogger(ProcessKill.class);

    public ProcessKill(){

    }

    public void run(){

    try{

    List> list = new ArrayList>();

    // 先通过ps aux | grep chrome命令,获取所有包含chrome文本内容的进程

    new ProcessExecutor().command("/bin/sh","-c","ps aux | grep chrome")

    .redirectOutput(new LogOutputStream() {

    protected void processLine(String line) {

    log.info("line========" + line);

    List lines = split(line.trim());

    // 判断进程启动时间,确定是否为执行超时休眠的进程

    String time = lines.get(8);

    String format = "[0-5][0-9]:[0-5][0-9]";

    Pattern p = Pattern.compile(format);

    Matcher m = p.matcher(time);

    boolean result = m.find();

    if(result == true) {

    log.info("time ========" + time + " " + result);

    }

    else{

    log.info("time xxxxxxxx" + time + " " + result);

    list.add(lines);

    }

    }

    })

    .execute();

    log.info("list========size:" + list.size());

    list.forEach(l->{

    log.info("list line========" + l);

    });

    for(int i = 0; i < list.size(); i++){

    List strs = list.get(i);

    try{

    String pid = strs.get(1);

    String stat = strs.get(7);

    String time = strs.get(8);

    String cmd = strs.get(10);

    log.info("pid========" + pid + ", " + stat + ", " + time + ", " + cmd);

    // 通过命令“kill -9 pid”杀掉进程

    String output = new ProcessExecutor().command("/bin/sh","-c","kill -9 " + pid)

    .readOutput(true).execute()

    .outputUTF8();

    log.info("kill========" + pid + ", " + output);

    }

    catch(Exception ex){

    ex.printStackTrace();

    }

    }

    }

    catch(Exception e){

    e.printStackTrace();

    }

    }

    public List split(String s){

    // ps aux | grep chrome 命令返回字段: USER,PID ,%CPU,%MEM,VSZ, RSS,TTY,STAT,START,TIME,COMMAND

    List list = new ArrayList();

    int blankCount = 0;

    StringBuffer sff = new StringBuffer();

    for(int i = 0; i < s.length(); i++){

    char c = s.charAt(i);

    if(list.size() < 10){

    if(c != ' '){

    sff.append(c);

    blankCount = 0;

    }

    else if(c == ' '){

    blankCount++;

    }

    if(blankCount == 1){

    list.add(sff.toString());

    sff = new StringBuffer();

    }

    }

    else{

    sff.append(c);

    }

    }

    if(sff.length() > 0){

    list.add(sff.toString());

    }

    return list;

    }

    public static void setLogFile(String name){

    Logger rootLogger = Logger.getRootLogger();

    Enumeration en = rootLogger.getAllAppenders();

    while (en.hasMoreElements()){

    Object obj = en.nextElement();

    if(obj instanceof RollingFileAppender){

    RollingFileAppender file = (RollingFileAppender)obj;

    file.setFile(name + ".log");

    file.activateOptions();

    }

    }

    }

    public static void main(String[] args){

    setLogFile("log/" + ProcessKill.class.getSimpleName());

    new ProcessKill().run();

    }

    }

    文末记录下ps和grep命令用法。

    ps 显示瞬间进程的状态

    参数:

    -A :所有的进程均显示出来,与 -e 具有同样的效用;

    -a : 显示现行终端机下的所有进程,包括其他用户的进程;

    -u :以用户为主的进程状态 ;

    x :通常与 a 这个参数一起使用,可列出较完整信息。

    ps aux

    USER:该进程属于那个使用者账号。

    PID :该进程的进程ID号。

    %CPU:该进程使用掉的 CPU 资源百分比;

    %MEM:该进程所占用的物理内存百分比;

    VSZ :该进程使用掉的虚拟内存量 (Kbytes)

    RSS :该进程占用的固定的内存量 (Kbytes)

    TTY :该进程是在那个终端机上面运作,若与终端机无关,则显示。另外, tty1-tty6 是本机上面的登入者程序,若为 pts/0 等等的,则表示为由网络连接进主机的程序。

    STAT:该程序目前的状态,主要的状态有:

    R :该程序目前正在运作,或者是可被运作;

    S :该程序目前正在睡眠当中,但可被某些讯号(signal) 唤醒。

    T :该程序目前正在侦测或者是停止了;

    Z :该程序应该已经终止,但是其父程序却无法正常的终止他,造成 zombie (疆尸) 程序的状态

    START:该进程被触发启动的时间;

    TIME :该进程实际使用 CPU 运作的时间。

    COMMAND:该程序的实际指令。

    ps -ef |grep java

    UID :程序被该 UID 所拥有

    PID :就是这个程序的 ID

    PPID :则是其上级父程序的ID

    C :CPU使用的资源百分比

    STIME :系统启动时间

    TTY :登入者的终端机位置

    TIME :使用掉的CPU时间。

    CMD :所下达的是什么指令

    grep命令的常用格式为:grep  [选项]  ”模式“  [文件]

    常用选项:

    -E :开启扩展(Extend)的正则表达式。

    -i :忽略大小写(ignore case)。

    -v :反过来(invert),只打印没有匹配的,而匹配的反而不打印。

    -n :显示行号

    -w :被匹配的文本只能是单词,而不能是单词中的某一部分,如文本中有liker,而我搜寻的只是like,就可以使用-w选项来避免匹配liker

    -c :显示总共有多少行被匹配到了,而不是显示被匹配到的内容,注意如果同时使用-cv选项是显示有多少行没有被匹配到。

    -o :只显示被模式匹配到的字符串。

    --color :将匹配到的内容以颜色高亮显示。

    -A n:显示匹配到的字符串所在的行及其后n行,after

    -B n:显示匹配到的字符串所在的行及其前n行,before

    -C n:显示匹配到的字符串所在的行及其前后各n行,context

    查看系统状态下的僵尸进程:

    ps -ef | grep defunct  后面尖括号里是defunct的都是僵尸进程。

    ps aux | grep -w 'Z' 其中状态为Z的代表僵尸进程。

    展开全文
  • Java 休眠

    2020-01-13 15:52:10
    sleep()使当前线程进入停滞状态(阻塞当前线程),让出CPU的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会。 实例1: import java.util.Date; public class Test{ ...
  • java线程休眠(sleep)

    千次阅读 2015-03-27 09:11:17
    自动醒来进入到可运行状态,不会马上进入运行状态,因为线程调度机制恢复线程的运行也需要时间,一个线程对象调用了sleep方法之后,并不会释放他所持有的所有对象锁,所以也就不会影响其他进程对象的运行。...
  • 守护进程是一个黑色地带的产物,无论是通过native的方式在Linux中fork进程达到,还是在Java层通过两个service守护的方式,都是不太友好的做法,据很多人反应,总有一些实际的业务场景中,希望自己的应用保持live状态...
  • Java 休眠(sleep)

    2021-01-14 17:42:52
    sleep()使当前线程进入停滞状态(阻塞当前线程),让出CPU的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会。 你可以让程序休眠一毫秒的时间或者到您的计算机的寿命长的...
  • 与其说并发调度,不如说,这就是一场“配对”游戏。线程模型在细说 Go 的调度模型之前,先来说说...1:1 , 一个用户线程对应到一个 OS线程上, 能利用到多核资源,但是上下文切换成本较高,这也是 Java Hotspot VM ...
  • 中断(休眠中, 受阻, 在等待某个条件的形成或接受到信号)3. 不可中断(收到信号不唤醒和不可运行, 进程必须等待直到有中断发生)4. 僵死(进程已终止, 但进程描述符存在, 直到父进程调用wait4系统调用后释放)5. 停止...
  • 1、toptop命令是Linux下常用的性能分析工具,能够实时显示系统中各个进程的资源占用状况,类似于Windows的任务管理器内容解释:PID:进程的...S表示休眠,R表示正在运行,Z表示僵死状态,N表示该进程优先值为负数%CP...
  • 线程程停止stop 不建议使用jdk自带的工具stop(), destroy() etc. 使用flag,当flag为true,线程工作,相反,则停止. public class TestStop implements Runnable{ ... //显示进程运行的次数.... while (flag){
  • (1)线程和进程通俗一点,进程就是一个应用程序在处理机上的一次执行过程,它是一个动态的概念,而线程是进程中的一部分,进程包含多个线程在运行。(2)java中实现线程的两种方式,第一种是继承Thread类,和实现...
  • sleep() 方法的作用是在指定的毫秒数内让当前“正在执行的线程”休眠(暂停执行)。这个“正在执行的线程”是指 this.currentThread() 返回的线程。例 1下面通过一个案例来理解使用 sleep() 方法判断线程是否活动的...
  • 1、进程与线程 1、什么是进程 程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念。而进程是程序在处理机上的一次执行过程,它是一个动态的概念。 进程是一个具有一定独立功能的程序,一个...
  • 关于进程休眠和唤醒(转)

    千次阅读 2009-05-17 22:33:00
    转自:http://bbs.java.ccidnet.com/read.php?tid=655240LKD中的讲解休眠(被阻塞)的进程处于一个特殊的...进程休眠有各种原因,但肯定都是为了等待一些事件。事件可能是一段时间、从文件I/O读更多数据,或者是某个硬件
  • java基础篇之 休眠(sleep、延时执行)

    万次阅读 2019-06-17 14:35:17
    sleep()使当前线程进入停滞状态(阻塞当前线程),让出CPU的使用、目的是不让当前线程独自霸占该进程所获的CPU资源,以留一定时间给其他线程执行的机会。 import java.util.*; public class SleepDemo { public...
  • 一、线程与进程 1、进程是资源分配的最小单位,线程是程序执行的最小单位(资源调度的最小单位) 2、进程有自己的独立地址空间,每启动一个进程,系统就会为它分配地址空间,建立数据表来维护代码段、堆栈段和...
  • 同一个进程中的3个线程是并发执行的,我们通过输出的时间点现象来看,线程的并发执行 最近突然越来感觉写博客似乎是一种很怡情的事情,可能是无聊,可能是心里面对现状的不满,希望通过学习改变自己,也只是希望...
  • 我看有的资料上是这样解释的:进程A获得自旋锁后,进行可能引起休眠的操作后(例如copy_from_user等),进程将会被切换出去,这个时候另外一个进程B企图获取本自旋锁,死锁就会发生。但是我想,即使进程A被切换出去,...
  • 进程与线程_基础(1) 进程与线程_基础(1) 1、什么是进程 2、进程的状态 3、CPU的时间片 4、线程基本概念 5、并行与并发 6、线程的基本使用 6.1、一种是继续Thread...7、线程的休眠 什么是释放CPU的时间片? ...

空空如也

空空如也

1 2 3 4 5 ... 15
收藏数 291
精华内容 116
热门标签
关键字:

java进程休眠

java 订阅