zoukankan      html  css  js  c++  java
  • Java多线程系列---“基础篇”07之 线程休眠

    转自:http://www.cnblogs.com/skywang12345/p/3479256.html   (含部分修改)

    概要

    本章,会对Thread中sleep()方法进行介绍。涉及到的内容包括:

    •  sleep()介绍
    •  sleep()示例
    •  sleep() 与 wait()的比较

    一. sleep()介绍

    sleep() 定义在Thread.java中。
    sleep() 的作用是让当前线程休眠,即当前线程会从“运行状态”进入到“休眠(阻塞)状态”。sleep()会指定休眠时间,线程休眠的时间会大于/等于该休眠时间;在线程重新被唤醒时,它会由“阻塞状态”变成“就绪状态”,从而等待cpu的调度执行。

    睡眠期间,该线程会让出CPU(但是不释放锁),但睡眠的时间不一定是确切的给定毫秒数,可能有一定的偏差,偏差与系统定时器和操作系统调度器的准确度和精度有关。

    睡眠期间,线程可以被中断,如果被中断,sleep会抛出InterruptedException

     二. sleep()示例

    下面通过一个简单示例演示sleep()的用法。

    // SleepTest.java的源码
    class ThreadA extends Thread{
        public ThreadA(String name){ 
            super(name); 
        } 
        public synchronized void run() { 
            try {
                for(int i=0; i <10; i++){ 
                    System.out.printf("%s: %d
    ", this.getName(), i); 
                    // i能被4整除时,休眠100毫秒
                    if (i%4 == 0)
                        Thread.sleep(100);
                } 
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        } 
    } 
    
    public class SleepTest{ 
        public static void main(String[] args){ 
            ThreadA t1 = new ThreadA("t1"); 
            t1.start(); 
        } 
    }

    运行结果

    复制代码
    t1: 0
    t1: 1
    t1: 2
    t1: 3
    t1: 4
    t1: 5
    t1: 6
    t1: 7
    t1: 8
    t1: 9
    复制代码

    结果说明
    程序比较简单,在主线程main中启动线程t1。t1启动之后,当t1中的计算i能被4整除时,t1会通过Thread.sleep(100)休眠100毫秒。

     三.  sleep() 与 wait()的比较

    我们知道,wait()的作用是让当前线程由“运行状态”进入“等待(阻塞)状态”的同时,也会释放同步锁。而sleep()的作用是也是让当前线程由“运行状态”进入到“休眠(阻塞)状态”。
    但是,wait()会释放对象的同步锁,而sleep()则不会释放锁。
    下面通过示例演示sleep()是不会释放锁的

    // SleepLockTest.java的源码
    public class SleepLockTest{ 
    
        private static Object obj = new Object();
    
        public static void main(String[] args){ 
            ThreadA t1 = new ThreadA("t1"); 
            ThreadA t2 = new ThreadA("t2"); 
            t1.start(); 
            t2.start();
        } 
    
        static class ThreadA extends Thread{
            public ThreadA(String name){ 
                super(name); 
            } 
            public void run(){ 
                // 获取obj对象的同步锁
                synchronized (obj) {
                    try {
                        for(int i=0; i <10; i++){ 
                            System.out.printf("%s: %d
    ", this.getName(), i); 
                            // i能被4整除时,休眠100毫秒
                            if (i%4 == 0)
                                Thread.sleep(100);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            } 
        } 
    }

    运行结果:(mynote:只有两种结果,要么t1先执行完,要么t2先执行完)

    复制代码
    t1: 0
    t1: 1
    t1: 2
    t1: 3
    t1: 4
    t1: 5
    t1: 6
    t1: 7
    t1: 8
    t1: 9
    t2: 0
    t2: 1
    t2: 2
    t2: 3
    t2: 4
    t2: 5
    t2: 6
    t2: 7
    t2: 8
    t2: 9
    复制代码

    结果说明
    主线程main中启动了两个线程t1和t2。t1和t2在run()会引用同一个对象的同步锁,即synchronized(obj)。在t1运行过程中,虽然它会调用Thread.sleep(100);但是,t2是不会获取cpu执行权的。因为,t1并没有释放“obj所持有的同步锁”!
    注意,若我们注释掉synchronized (obj)后再次执行该程序,t1和t2是可以相互切换的。下面是注释调synchronized(obj) 之后的源码:

    // SleepLockTest.java的源码(注释掉synchronized(obj))
    public class SleepLockTest{ 
    
        private static Object obj = new Object();
    
        public static void main(String[] args){ 
            ThreadA t1 = new ThreadA("t1"); 
            ThreadA t2 = new ThreadA("t2"); 
            t1.start(); 
            t2.start();
        } 
    
        static class ThreadA extends Thread{
            public ThreadA(String name){ 
                super(name); 
            } 
            public void run(){ 
                // 获取obj对象的同步锁
    //            synchronized (obj) {
                    try {
                        for(int i=0; i <10; i++){ 
                            System.out.printf("%s: %d
    ", this.getName(), i); 
                            // i能被4整除时,休眠100毫秒
                            if (i%4 == 0)
                                Thread.sleep(100);
                        }
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
    //            }
            } 
        } 
    }

    其中一种运行结果:

    t1: 0
    t2: 0
    t1: 1
    t1: 2
    t2: 1
    t2: 2
    t2: 3
    t2: 4
    t1: 3
    t1: 4
    t2: 5
    t2: 6
    t1: 5
    t1: 6
    t1: 7
    t1: 8
    t2: 7
    t2: 8
    t1: 9
    t2: 9
  • 相关阅读:
    java线程池实例
    多线程生产者消费者实例
    js函数
    if else语句
    JS中Math对象的常用方法说明
    引用类型的自定义数据排序——高淇JAVA300讲笔记
    引用类型的内置类大小比较(用Comparator接口实现)——高淇JAVA300讲笔记之Comparator接口
    引用类型的内置类大小比较(用Comparable接口实现)——高淇JAVA300讲笔记之Comparable接口
    冒泡排序——高淇JAVA300讲笔记之冒泡排序
    分拣存储02——高淇300讲笔记之分拣存储
  • 原文地址:https://www.cnblogs.com/Hermioner/p/9860414.html
Copyright © 2011-2022 走看看