广东网站制作,广州网站建设规划,php网站开发总结,怎么给网站创建二维码一.前言 关于并发编程这块, 线程的一些基础知识我们得搞明白, 本篇文章来说一下这两个方法的区别,对Android中的HandlerThread机制原理可以有更深的理解, HandlerThread源码理解,请查看笔者的这篇博客:
HandlerThread源码理解_handlerthread 源码_broadview_java的博客-CSDN博…一.前言 关于并发编程这块, 线程的一些基础知识我们得搞明白, 本篇文章来说一下这两个方法的区别,对Android中的HandlerThread机制原理可以有更深的理解, HandlerThread源码理解,请查看笔者的这篇博客:
HandlerThread源码理解_handlerthread 源码_broadview_java的博客-CSDN博客 二.区别
2.1 sleep方法
public static native void sleep(long millis)方法是Thread的静态方法很显然它是让当前线程按照指定的时间休眠其休眠时间的精度取决于处理器的计时器和调度器。需要注意的是如果当前线程获得了锁sleep方法并不会失去锁。 Thread类中的静态方法sleep()当一个执行中的线程调用了Thread的sleep()方法后调用线程会暂时让出时间的执行权这期间不参与cpu的调度但是该线程持有的锁是不让出的。时间到了会正常返回线程处于就绪状态然后参与cpu调度获取到cpu资源之后就可以运行。 我们通过这个Demo来看下 public class SleepTest {private static Object lock new Object();public static void main(String[] args) {new Thread(()-{synchronized (lock) {System.out.println(线程A休眠10秒不放弃锁);try {Thread.sleep(10000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(A休眠10秒醒来);}}).start();new Thread(()-{synchronized (lock){System.out.println(线程B休眠5秒不放弃锁);try {Thread.sleep(5000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(B休眠5秒醒来);}}).start();}
} 打印结果如下: 线程A休眠10秒不放弃锁
A休眠10秒醒来
线程B休眠5秒不放弃锁
B休眠5秒醒来 或 线程B休眠5秒不放弃锁
B休眠5秒醒来
线程A休眠10秒不放弃锁
A休眠10秒醒来 解释如下:
无论执行多少次都是先A输出再B输出 或者 先B输出再A输出不会出现交叉输出的情况 因为A获取到锁之后即使是sleep也不会释放锁因B获取不到锁也就无法执行。
总结: sleep方法不会释放锁 2.2 wait方法
Object.wait方法会释放锁对象 一个调用了某个对象的 Object.wait 方法的线程会等待另一个线程调用此对象的 Object.notify()方法 或 Object.notifyAll()方法。
其实waiting状态并不是一个线程的操作它体现的是多个线程间的通信可以理解为多个线程之间的协作关系, 也是java并发编程要处理的核心问题.
当多个线程协作时比如AB线程如果A线程在Runnable可运行状态中调用了wait()方法那么A线程就进入了Waiting无限等待状态同时失去了同步锁。
假如这个时候B线程获取到了同步锁在运行状态中调用了notify()方法那么就会将无限等待的A线程唤醒。
注意是唤醒如果获取到锁对象那么A线程唤醒后就进入Runnable可运行状态如果没有获取锁对象那么就进入到Blocked锁阻塞状态。
我们来看这个Demo : public class wakeLockTest {private static Object lock new Object(); public static void main(String[] args) {Thread thread1 new Thread(new Runnable1(), 线程1);thread1.start();Thread thread2 new Thread(new Runnable2(), 线程2);thread2.start();}static class Runnable1 implements Runnable{Overridepublic void run() {synchronized (lock) {try {lock.wait();System.out.println(当前线程名: Thread.currentThread().getName());} catch (InterruptedException e) {e.printStackTrace();}}}}static class Runnable2 implements Runnable{Overridepublic void run() {synchronized (lock) {lock.notify();System.out.println(当前线程名: Thread.currentThread().getName());}}}
} 如果不加同步锁相关的代码, 从代码流程来看, 线程1 先执行, 线程2再执行,肯定会打印
当前线程名: 线程1 当前线程名: 线程2
加入锁相关的代码后,打印如下:
三. 总结 sleep方法是Thread类的方法线程通过调用该方法进入休眠状态主动让出CPU从而CPU可以执行其他的线程。经过sleep指定的时间后CPU回到这个线程上继续往下执行。
如何当前线程进入了同步锁sleep()方法并不会释放锁。即使当前线程使用sleep方法让出了cpu但其他被同步锁挡住了的线程也无法得到执行。
使用场合 线程的调度执行是按照其优先级的高低顺序进行的当高级别的线程未死亡时低级别的线程没有机会获得CPU资源。有时优先级高的线程需要优先级低的线程完成一些辅助工作或者优先级高的线程需要完成一些比较费时的工作此时优先级高的线程应该让出CPU资源使得优先级低的线程有机会执行。为了达到这个目的优先级高的线程可以在自己的run()方法中调用sleep方法来使自己放弃CPU资源休眠一段时间。 wait()方法
Obj.wait()与Obj.notify()必须要与synchronized(Obj)一起使用也就是wait,与notify是针对已经获取了Obj锁进行操作从语法角度来说就是Obj.wait(),Obj.notify必须在synchronized(Obj){...}语句块内。
从功能上来说wait就是说线程在获取对象锁后主动释放对象锁同时本线程休眠。直到有其它线程调用对象的notify()唤醒该线程才能继续获取对象锁并继续执行。
相应的notify()就是对对象锁的唤醒操作。但有一点需要注意的是notify()调用后并不是马上就释放对象锁的而是在相应的synchronized(){}语句块执行结束后才会释放锁.
两者区别 1.sleep()方法属于Thread类的。; wait()方法则是属于Object类的; 2.sleep方法不会释放锁而wait方法会释放锁 3.waitnotify和notifyAll只能在同步控制方法或者同步控制块里面使用而sleep可以在任何地方使用 4.sleep可以自然醒wait必须等待被唤醒.