简述sleep方法和wait方法的区别,sleep方法和yield方法的区别

本文详细介绍了Java中sleep、wait和yield方法的区别,强调了它们在线程控制中的不同作用。sleep方法使线程暂停并释放处理器,wait方法用于线程同步,释放同步锁,而yield方法则让当前线程进入就绪状态,给相同或更高优先级的线程执行机会。此外,文章指出stop和suspend方法的不安全性,推荐使用退出标志来安全终止线程。
摘要由CSDN通过智能技术生成

简述sleep方法和wait方法的区别,sleep方法和yield方法的区别

sleep方法是Thread类的一个静态方法,其作用是使运行中的线程暂时停止指定的毫秒数,从而该线程进入阻塞状态并让出处理器,将执行的机会让给其他线程。但是这个过程中监控状态始终保持,当sleep的时间到了之后线程便会自动恢复。

wait是Object类的方法,它是用来实现线程同步的。当调用某个对象的wait方法后,当前线程会被阻塞并释放出同步锁,知道其他线程调用了该对象的notify方法或者notifyALL方法来唤醒线程。所以wait方法和notify(或notifyALL)应当成对出现以宝成线程间的协调运行。

yield方法容易与sleep方法混淆,请务必牢记,yield的作用是让当前的线程暂停,但不会像sleep那样的阻塞该线程,而是使该线程进入就绪状态。总结起来,yield方法与sleep方法的主要区别在于:

  • sleep方法暂停当前线程之后,会给其他线程执行机会而不会考虑其他线程的优先性。但是yield方法只会给优先级相同或者优先级更高的线程执行机会。
  • sleep方法执行后的线程进入阻塞状态,而执行了yield方法之后,当前线程便会进入就绪状态,
  • 由于sleep方法的声明抛出了InterruptedException异常,所以在调用sleep方法时需要catch该异常或者抛出该异常,而yield方法没有声明抛出异常。
  • sleep方法比yield方法具有更好的可移植性。
简述Java中为什么不建议使用stop和suspend方法终止线程

stop方法和suspend方法的缺点

在Java中可以使用stop方法停止一个线程,使得该线程进入死亡状态。但是使用这种方法结束一个线程是不安全的,在编写程序时应禁止使用这种方法。

之所以说stop方法是线程不安全的,是因为一旦调用了Thread.stop()方法,工作线程将抛出一个ThreadDeath异常,这会导致run方法结束执行,而且结束的点是不可控的,也就是说,它可能执行到run方法的任何一个位置就突然中止了。同时它还会释放掉该线程所释放的锁,这样其他因为请求该锁对象而被阻塞的线程就会获得锁对象而继续执行下去。一般情况下,加速的目的是保护数据的一致性,然后在调用Thread.stop()后线程立即终止,那么被保护的数据就有可能出现不一致的情况(数据的状态不可知)。同时,该线程所持有的锁突然被释放,其他线程获得同步锁后可以进入临界区使用这些被破坏的数据,这将有可能导致一些很奇怪的应用程序错误发生,而且这种错误非常难以debug。所以在这里再次重申,不要试图用stop方法结束一个线程。

suspend方法可以阻塞一个线程,然而该线程虽然被堵塞,但它仍然持有它之前获得的锁。这样其他线程都不能访问相同锁对象保护的资源,除非被阻塞的线程被重新恢复。如果此时只有一个线程能够恢复这个被suspend的线程,但前提是先要访问被该线程锁定的临界资源,这样便产生了死锁。所以在编写程序时,应尽量避免使用suspend,如确实需要阻塞一个线程的运行,最好使用wait()方法,这样既可以阻塞掉当前正在执行的线程,同时又使得该线程不至于陷入死锁。

答案:

stop方法是不安全的,可能产生不可预料的结果;suspend方法可能导致死锁。

如何终止一个线程
  1. stop方法和suspend方法的缺点
  2. 终止一个线程的方法

方法一:使用退出标志。

正常情况下,当Thread或Runnable类的run方法执行完毕后该线程即可结束,但是有些情况下run方法可能永远不会通知,例如,在服务器端程序中使用线程监听用户请求,或者执行其他需要循环处理的任务。这时如果希望有机会终止该线程,可将执行的任务放在一个循环中(例如while循环),并设置一个boolean类型的循环结束标志。如果想要使while循环在某一个特定条件下退出,就可以通过设置这个标志位true或者false来控制while循环是否退出。这样将线程结束的控制逻辑与线程本身逻辑结合在一起,可以保证线程安全可控地控制。请看下面的例子:

public class test{
    public static volative boolean exit=false;
    public static void main(String[] args){
        new Thread(){
            public void run(){
                System.out.println("thread start....");
                while(!exit){//死循环,正常情况下是不会停止的
                    try{
                        Thread.sleep(1000);
                    }cach(InterruptedExcepion e){
                        e.ptitStackTrace;
                    }
                    System.out.println("thread run");
                }
                System.out.println("thread end....");
            };
        }.start();
        new Thread(){
            public void run(){
                try{
                    Thread.sleep(1000*5);
                }catch(InterruptedException e){
                    e.printStackTrace();
                }
                exit=true;
            };
        }.start();
    }
}

在上面这段程序中的main方法中创建了两个线程,第一个线程的run方法中有一个while循环,该循环通过boolean型变量exit控制是否结束。因为变量exit的初始值位false,所以如果不修改该变量,第一个线程中的run方法将不会停止,也就是说,第一个线程将永远不会终止,并且间隔1s在屏幕上打印出一条"thread run"字符串。

第二个线程的作用是通过修改变量exit的值来控制第一个线程的执行。当变量exit被置为ture,第一个线程的while循环就可以终止,所以run()方法就能执行完毕,从而安全退出第一个线程。

注意,boolean变量exit被声明为volatile,volatile会保证变量一个线程中的每一步操作在另一个线程都是可见的,所以这样可以确保将exit置为true后可以安全退出第一个线程。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值