asleep和sleep的区别notify的区别

&&国之画&&&&&&
版权所有 京ICP备号-2
迷上了代码!sleep方法没有释放锁:不让出资源wait方法释放了锁:使得其他线程可以使用同步控制块或者方法sleep不释放锁 线程是进入阻塞状态还是就绪状态?sleep是不是还占着CPU,是互斥还是同步?
首先,要记住这个差别,“sleep是Thread类的方法,wait是Object类中定义的方法”。尽管这两个方法都会影响线程的执行行为,但是本质上是有区别的。Thread.sleep不会导致锁行为的改变,如果当前线程是拥有锁的,那么Thread.sleep不会让线程释放锁。如果能够帮助你记忆的话,可以简单认为和锁相关的方法都定义在Object类中,因此调用Thread.sleep是不会影响锁的相关行为。Thread.sleep和Object.wait都会暂停当前的线程,对于CPU资源来说,不管是哪种方式暂停的线程,都表示它暂时不再需要CPU的执行时间。OS会将执行时间分配给其它线程。区别是,调用wait后,需要别的线程执行notify/notifyAll才能够重新获得CPU执行时间。线程的状态参考 Thread.State的定义。新创建的但是没有执行(还没有调用start())的线程处于“就绪”,或者说Thread.State.NEW状态。Thread.State.BLOCKED(阻塞)表示线程正在获取锁时,因为锁不能获取到而被迫暂停执行下面的指令,一直等到这个锁被别的线程释放。BLOCKED状态下线程,OS调度机制需要决定下一个能够获取锁的线程是哪个,这种情况下,就是产生锁的争用,无论如何这都是很耗时的操作。
先说下两者的共同点:都会阻塞当前线程。&br&不同点:&br&&ul&&li&sleep不会交出任何已获得的对象锁&/li&&/ul&&blockquote&The thread does not lose ownership of any monitors &a href=&///?target=http%3A///javase/7/docs/api/java/lang/Thread.html%23sleep%28long%29& class=& wrap external& target=&_blank& rel=&nofollow noreferrer&&Thread (Java Platform SE 7 )&i class=&icon-external&&&/i&&/a&&/blockquote&&ul&&li&wait会交出调用wait对象的对象锁。而且wait存在notify方法来唤醒调用wait的线程,这个是sleep没有的。&/li&&/ul&
先说下两者的共同点:都会阻塞当前线程。不同点:sleep不会交出任何已获得的对象锁The thread does not lose ownership of any monitors wait会交出调用wait对象的对象锁。而且wait存在notify方法来唤醒调用wait的线程,这个是…
&ul&&li&&b&sleep&/b& 是让线程进入阻塞状态,一定时间之后回到非阻塞状态,从而可以重新获得 CPU。&/li&&li&&b&wait&/b& 调用的时候需要先获得该 Object 的锁,调用 wait 后,会把当前的锁释放掉同时阻塞住;当别的线程调用该 Object 的 notify/notifyAll 之后,有可能得到 CPU,同时重新获得锁。由于有如上描述锁的设计,只要在 notify 的时候首先获得锁,就可以保证 notify 的时候或者处于 wait 线程获得锁之前,或者正在 wait,从而保证不会丢掉这次 notify 信息。&/li&&/ul&
sleep 是让线程进入阻塞状态,一定时间之后回到非阻塞状态,从而可以重新获得 CPU。wait 调用的时候需要先获得该 Object 的锁,调用 wait 后,会把当前的锁释放掉同时阻塞住;当别的线程调用该 Object 的 notify/notifyAll 之后,有可能得到 CPU,同时重新…
已有帐号?
无法登录?
社交帐号登录
资深码农,技术死宅 ( ?° ?? ?°)<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
您的访问请求被拒绝 403 Forbidden - ITeye技术社区
您的访问请求被拒绝
亲爱的会员,您的IP地址所在网段被ITeye拒绝服务,这可能是以下两种情况导致:
一、您所在的网段内有网络爬虫大量抓取ITeye网页,为保证其他人流畅的访问ITeye,该网段被ITeye拒绝
二、您通过某个代理服务器访问ITeye网站,该代理服务器被网络爬虫利用,大量抓取ITeye网页
请您点击按钮解除封锁&[转]进程sleep,wait,join,yield,notify(),notifyAll(),run(),start(),Synchronized的区别
进程sleep,wait,join,yield,notify(),notifyAll(),run(),start(),Synchronized的区别
使当前线程(即调用该方法的线程)暂停执行一段时间,让其他线程有机会继续执行,但它并不释放对象锁。也就是如果有Synchronized同步块,其他线程仍然不同访问共享数据。注意该方法要捕获异常
比如有两个线程同时执行(没有Synchronized),一个线程优先级为MAX_PRIORITY,另一个为MIN_PRIORITY,如果没有Sleep()方法,只有高优先级的线程执行完成后,低优先级的线程才能执行;但当高优先级的线程sleep(5000)后,低优先级就有机会执行了。
总之,sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的线程有执行的机会。
join()方法使调用该方法的线程在此之前执行完毕,也就是等待调用该方法的线程执行完毕后再往下继续执行。注意该方法也要捕获异常。
它与sleep()类似,只是不能由用户指定暂停多长时间,并且yield()方法只能让同优先级的线程有执行的机会。
4.wait()和notify()、notifyAll()
这三个方法用于协调多个线程对共享数据的存取,所以必须在Synchronized语句块内使用这三个方法。前面说过Synchronized这个关键字用于保护共享数据,阻止其他线程对共享数据的存取。但是这样程序的流程就很不灵活了,如何才能在当前线程还没退出Synchronized数据块时让其他线程也有机会访问共享数据呢?此时就用这三个方法来灵活控制。
wait()方法使当前线程暂停执行并释放对象锁标志,让其他线程可以进入Synchronized数据块,当前线程被放入对象等待池中。当调用
notify()方法后,将从对象的等待池中移走一个任意的线程并放到锁标志等待池中,只有
锁标志等待池中的线程能够获取锁标志;如果锁标志等待池中没有线程,则notify()不起作用。
notifyAll()则从对象等待池中移走所有等待那个对象的线程并放到锁标志等待池中。
注意 这三个方法都是java.lang.Ojbect的方法!&
5.run()和start()
这两个方法应该都比较熟悉,把需要并行处理的代码放在run()方法中,start()方法启动线程将自动调用
run()方法,这是由Java的内存机制规定的。并且run()方法必须是public访问权限,返回值类型为void。
6.关键字Synchronized
这个关键字用于保护共享数据,当然前提是要分清哪些数据是共享数据。每个对象都有一个锁标志,当一个线程访问该对象时,被Synchronized修饰的数据将被“上锁”,阻止其他线程访问。当前线程访问完这部分数据后释放锁标志,其他线程就可以访问了。
public class ThreadTest implements Runnable {
&& public synchronized void
&&& for(int
i=0;i&10;i++){
System.out.println(" " + i);
&& public static void
main(String[] args){
&&& Runnable r1
= new ThreadTest();
&&& Runnable r2
= new ThreadTest();
&&& Thread t1 =
new Thread(r1);
&&& Thread t2 =
new Thread(r2);
t1.start();
t2.start();
以上这段程序中的 i
变量并不是共享数据,也就是这里的Synchronized关键字并未起作用。因为t1,t2两个线程是两个对象(r1,r2)的线程。不同的对象其数据是不同的,所以r1和r2两个对象的i变量是并不是共享数据。
当把代码改成如下:Synchronized关键字才会起作用
public class ThreadTest implements Runnable {
&& public synchronized void
&&& for(int
i=0;i&10;i++){
System.out.println(" " + i);
&& public static void
main(String[] args){
//&&& Runnable
r1 = new ThreadTest();
//&&& Runnable
r2 = new ThreadTest();
&&& Runnable r =
new ThreadTest();
//&&& Thread t1
= new Thread(r1);
//&&& Thread t2
= new Thread(r2);
&&& Thread t1 =
new Thread(r);
&&& Thread t2 =
new Thread(r);
t1.start();
t2.start();
---------------
JAVA线程的四种状态
线程有四种状态,任何一个线程肯定处于这四种状态中的一种:
产生(New):线程对象已经产生,但尚未被启动,所以无法执行。如通过new产生了一个线程对象后没对它调用start()函数之前。
可执行(Runnable):每个支持多线程的系统都有一个排程器,排程器会从线程池中选择一个线程并启动它。当一个线程处于可执行状态时,表示它可能正处于线程池中等待排排程器启动它;也可能它已正在执行。如执行了一个线程对象的start()方法后,线程就处于可执行状态,但显而易见的是此时线程不一定正在执行中。
3) 死亡(Dead):当一个线程正常结束,它便处于死亡状态。如一个线程的run()函数执行完毕后线程就进入死亡状态。
停滞(Blocked):当一个线程处于停滞状态时,系统排程器就会忽略它,不对它进行排程。当处于停滞状态的线程重新回到可执行状态时,它有可能重新执行。如通过对一个线程调用wait()函数后,线程就进入停滞状态,只有当两次对该线程调用notify或notifyAll后它才能两次回到可执行状态。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。java线程同步原理及wait,notify的用法及与sleep的区别
一。 java线程同步原理
java会为每个object对象分配一个monitor,当某个对象的同步方法(synchronized methods
)被多个线程调用时,该对象的monitor将负责处理这些访问的并发独占要求。
当一个线程调用一个对象的同步方法时,JVM会检查该对象的monitor。如果monitor没有被占用,那么这个线程就得到了monitor的占有
权,可以继续执行该对象的同步方法;如果monitor被其他线程所占用,那么该线程将被挂起,直到monitor被释放。
当线程退出同步方法调用时,该线程会释放monitor,这将允许其他等待的线程获得monitor以使对同步方法的调用执行下去。
注意:Java对象的monitor机制和传统的临界检查代码区技术不一样。java的一个同步方法并不意味着同时只有一个线程独占执行,但临界检查代码
区技术确实会保证同步方法在一个时刻只被一个线程独占执行。Java的monitor机制的准确含义是:任何时刻,对一个指定object对象的某同步方
法只能由一个线程来调用。
java对象的monitor是跟随object实例来使用的,而不是跟随程序代码。两个线程可以同时执行相同的同步方法,比如:一个类的同步方法是
xMethod(),有a,b两个对象实例,一个线程执行a.xMethod(),另一个线程执行b.xMethod().
互不冲突。
二。 wait()、notify(),notifyAll()的使用
obj.wait()方法将使本线程挂起,并释放obj对象的monitor。只有其他线程调用obj对象的notify()或notifyAll()时,才可以被唤醒。
obj.notifyAll()方法唤醒所有该obj对象相关的沉睡线程,然后被唤醒的众多线程开始竞争obj对象的monitor占有权,最终得到的那个线程会继续执行下去,但其他线程还将继续等待。
obj.notify()方法是随机唤醒一个沉睡线程。
wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,
synchronized(x){
x.notify()
//或者wait()
以上内容说明了为什么调用wait(),notify(),notifyAll()的线程必须要拥有obj实例对象的monitor占有权。
每个对象实例都有一个等待线程队列。这些线程都是等待对该对象的同步方法的调用许可。对一个线程来说,有两种方法可以进入这个等待线程队列。一个是当其他线程执行同步方法时,自身同时也要执行该同步方法;另一个是调用obj.wait()方法。
当同步方法执行完毕或者执行wait()时,其他某个线程将获得对象的访问权。当一个线程被放入等待队列时,必须要确保可以通过notify()的调用来解冻该线程,以使其能够继续执行下去。
三。 wait()与sleep()的区别:
sleep()函数是Thread类的静态函数,不涉及到线程间同步概念,仅仅为了让一个线程自身获得一段沉睡时间。sleep可以在任何地方使用。
wait函数是object类的函数,要解决的问题是线程间的同步,该过程包含了同步锁的获取和释放,调用wait方法将会将调用者的线程挂起,直到其他线程调用同一个对象的notify方法才会重新激活调用者。
注意,线程调用notify()之后,只有该线程完全从
synchronized代码里面执行完毕后,monitor才会被释放,被唤醒线程才可以真正得到执行权。
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。

我要回帖

更多关于 inform和notify的区别 的文章

 

随机推荐