线程学习->05wait、notify、yield、joi

2017-10-12  本文已影响14人  冉桓彬

一、参考文章:

二、基础api:

1. Object.wait();
2. Object.notify();
3. Thread.join();
4. Thread.yield();
5. Thread.sleep();

三、wait与notify:

3.1 demo(wait与notify):
public static void waitNotifyTest() {
    final Object obj = new Object();
    new Thread(new Runnable() {
        @Override
        public void run() {
            LogUtils.log(getClass(), "1. 线程A正在尝试获取锁");
            synchronized (obj) {
                try {
                    LogUtils.log(getClass(), "2. 线程A获取锁成功");
                    SystemClock.sleep(2000);
                    LogUtils.log(getClass(), "3. 线程A正在尝试挂起");
                    obj.wait();
                    LogUtils.log(getClass(), "4. 线程A挂起结束");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }).start();
    new Thread(new Runnable() {
        @Override
        public void run() {
            LogUtils.log(getClass(), "5. 线程B正在尝试获取锁");
            synchronized (obj) {
                LogUtils.log(getClass(), "6. 线程B获取锁成功");
                SystemClock.sleep(2000);
                LogUtils.log(getClass(), "7. 线程B正在尝试唤醒线程A");
                obj.notify();
                LogUtils.log(getClass(), "8. 线程B唤醒线程A结束");
            }
        }
    }).start();
}

打印结果如下:

05-06 18:35:54.698 4020-4063/com.test V/AndroidTest: ->1. 线程A正在尝试获取锁
05-06 18:35:54.698 4020-4063/com.test V/AndroidTest: ->2. 线程A获取锁成功
05-06 18:35:54.698 4020-4064/com.test V/AndroidTest: ->5. 线程B正在尝试获取锁
05-06 18:35:56.698 4020-4063/com.test V/AndroidTest: ->3. 线程A正在尝试挂起
05-06 18:35:56.748 4020-4064/com.test V/AndroidTest: ->6. 线程B获取锁成功
05-06 18:35:58.748 4020-4064/com.test V/AndroidTest: ->7. 线程B正在尝试唤醒线程A
05-06 18:35:58.748 4020-4064/com.test V/AndroidTest: ->8. 线程B唤醒线程A结束
05-06 18:35:58.748 4020-4063/com.test V/AndroidTest: ->4. 线程A挂起结束

在没看占小狼博客之前我是懵逼的;

3.2 关于demo有几个简短的结论:
3.3 关于demo有几个疑问:
3.4 复制一段<深入理解java虚拟机>(P391):

  synchronized关键字经过编译之后, 会在同步块的前后分别形成monitorenter和monitorexit这两个字节码指令, 这两个字节码都需要一个reference类型的参数来指明要锁定和解锁的对象; 如果java程序中的synchronized明确指定了对象参数, 那就是这个对象的reference, 如果没有明确指定, 那就根据synchronized修饰的实例方法还是类方法, 去取对应的对象实例或Class对象来作为锁对象;
  在执行monitorenter指令时, 首先尝试获取对象的锁(monitor), 成功--锁的计数器加1, 失败--线程被挂起, 直到锁被释放;

3.5 wait/notify:

汇编搞不懂啊, 只记结论太伤了;
总结一下就是:

四、Thread.yield:

五、Thread.join:

上一篇 下一篇

猜你喜欢

热点阅读