前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >线程常用方法辨析(1)

线程常用方法辨析(1)

作者头像
黑洞代码
发布2021-01-14 15:45:05
2490
发布2021-01-14 15:45:05
举报

线程常用方法辨析(1)

概述


1.sleep()方法

2.wait()方法

3.notify()/notifyAll()

4.总结

第1节 sleep()方法

1. sleep()方法的作用是让当前线程暂停指定的时间(毫秒)

2. sleep()方法只是暂时让出CPU的执行权,并不释放锁

3. 由于对象锁没有被释放,其他线程仍然无法访问这个对象

4. sleep()方法不需要在同步的代码块中执行,wait()方法必须要在同步的代码块中执行

5. sleep()可以通过interrupt()方法打断线程的暂停状态

6. sleep()只是线程的操作,用于短时间暂停线程,不涉及线程间通信

7. sleep()是Thread类的方法

代码语言:javascript
复制
public class SleepTest {

    /**
     * sleep()方法不会释放锁,因此线程是按照先后顺序执行的
     */
    public synchronized void sleepMethod(){
        System.out.println("Sleep start : "
                + Thread.currentThread().getName());
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("Sleep end : "
                + Thread.currentThread().getName());
    }

    /**
     * wait()方法会释放锁,因此一旦调用wait()方法就会造成其他线程运行
     */
    public synchronized void waitMethod(){
        System.out.println("Wait start : "
                + Thread.currentThread().getName());
        synchronized (this){
            try {
                wait(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("Wait end :"
                + Thread.currentThread().getName());
    }

    public static void main(String[] args) {

        final SleepTest test1 = new SleepTest();

        for(int i = 0; i < 5; i++){
            new Thread(() -> test1.sleepMethod()).start();
        }


        try {
            //暂停十秒,等上面程序执行完成
            Thread.sleep(10000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println("-----分割线-----");

        final SleepTest test2 = new SleepTest();

        for(int i = 0; i < 5; i++){
            new Thread(() -> test2.waitMethod()).start();
        }

    }
}

执行结果如下:

代码语言:javascript
复制
Sleep start : Thread-0
Sleep end : Thread-0
Sleep start : Thread-4
Sleep end : Thread-4
Sleep start : Thread-3
Sleep end : Thread-3
Sleep start : Thread-2
Sleep end : Thread-2
Sleep start : Thread-1
Sleep end : Thread-1
-----分割线-----
Wait start : Thread-5
Wait start : Thread-6
Wait start : Thread-8
Wait start : Thread-7
Wait start : Thread-9
Wait end :Thread-6
Wait end :Thread-8
Wait end :Thread-9
Wait end :Thread-7
Wait end :Thread-5

第2节 wait()方法


1. wait()/notify()方法通常成对出现

2. wait()/notify()方法需要获取对象锁方可调用

3. wait()/notify()方法要写在同步代码块或者同步方法内

4. 一旦调用wait()方法,其他线程将可以访问这个对象

5. 当一个线程执行到wait()方法时,它就进入到一个和该对象相关的等待池中,

同时失去了对象的锁,可以允许其它的线程执行一些同步操作。

6. wait()可以通过interrupt()方法打断线程的暂停状态,从而使线程立刻抛出中断异常

7. 重获对象锁:

a)设置wait()方法的参数,如wait(1000)表明借出去1秒钟之后,自动收回锁

b)让借锁的线程通知(notify)当前线程,借锁线程用完了当前线程马上就收回来

8. wait()/notify()是Object类的方法

第3节 notify()/notifyAll()


1. notify()唤醒在此对象监视器(对象锁)上等待的单个线程

2. 当它被一个notify()方法唤醒时,等待池中的线程就被放到了锁池中

(synchronized部分会详细讲解等待池和锁池,此处简单理解即可)

3. 该线程将等待从锁池中获得锁,然后回到wait()前的现场

4. notifyAll()唤醒在此对象监视器(对象锁)上等待的所有线程

5. 唤醒的线程的顺序——LIFO(Last In First Out,后进先出)

6. wait()/notify()/notifyAll()涉及线程间的通信

代码语言:javascript
复制
public class WaitClassDemo {

    private static SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");

    public static void main(String[] args) {
        Object obj = new Object();
        for (int i = 0; i < 5; i++) {
            new WaitThread(i + "", obj).start();
        }
        new NotifyThread(obj).start();
    }

    /**
     * 调用wait()方法的线程
     */
    static class WaitThread extends Thread {

        Object obj;

        public WaitThread(String name, Object obj) {
            setName("WaitThread" + name);
            this.obj = obj;
        }

        @Override
        public void run() {
            synchronized (obj) {
                System.out.println(sdf.format(new Date()) + " " + getName() + " before wait()");
                try {
                    obj.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(sdf.format(new Date()) + " " + getName() + " after wait()");
            }
        }
    }

    /**
     * 调用notify()/notifyAll()
     */
    static class NotifyThread extends Thread {

        Object obj;

        public NotifyThread(Object obj) {
            setName("NotifyThread");
            this.obj = obj;
        }

        @Override
        public void run() {
            synchronized (obj) {
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(sdf.format(new Date()) + " NotifyThread before notify()");
                // 唤醒所有线程 用notifyAll()会按照后进先出(LIFO)的原则恢复线程
                obj.notifyAll();
                try {
                    Thread.sleep(5000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(sdf.format(new Date()) + " NotifyThread after notify()");
            }
        }
    }
}

执行结果如下:

代码语言:javascript
复制
20:11:44 WaitThread0 before wait()
20:11:44 WaitThread4 before wait()
20:11:44 WaitThread3 before wait()
20:11:44 WaitThread2 before wait()
20:11:44 WaitThread1 before wait()
20:11:49 NotifyThread before notify()
20:11:54 NotifyThread after notify()
20:11:54 WaitThread1 after wait()
20:11:54 WaitThread2 after wait()
20:11:54 WaitThread3 after wait()
20:11:54 WaitThread4 after wait()
20:11:54 WaitThread0 after wait()

第4节 总结


1. wait()、notify()、notifyAll()是三个定义在Object类里的方法,可以用来控制线程的状态

2. 调用了wait()方法就会使持有该对象的线程把该对象的控制权交出去,然后处于等待状态

3. 对象调用了notify()方法就会通知某个正在等待这个对象的控制权的线程可以继续运行

4. 对象调用了notifyAll()方法就会通知所有等待这个对象控制权的线程继续运行

5. wait()方法有三个重载的方法wait()/wait(long)/wait(long,int)

6. sleep()方法的作用是让当前线程暂停指定的时间

7. sleep()方法只是暂时让出CPU的执行权,并不释放锁

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-06-18,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 落叶飞翔的蜗牛 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档