线程的sleep、yield、join、停止方法

1、线程休眠 sleep(long time) 单位为毫秒
线程休眠指的是让线程暂缓执行以一下,等到了预计时间之后再恢复执行
sleep方法会让当前线程立即交出CPU,但不会释放对象锁,即使当前持有某个对象的的线程调用sleep方法休眠了,其他线程也无法持有该对象;

public class Test implements Runnable {
    private int ticket = 100;
    @Override
    public void run() {
        synchronized (this) {//Runnable对象
            while (ticket > 0) {
                try {
                //sleep不会释放对象锁,即使当前线程休眠了,其他线程也无法拿到该runable对象,当该线程休眠结束后,继续执行;
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }

                System.out.println(Thread.currentThread().getName() + "还剩" + ticket-- + "张票");
            }
        }
    }
    public static void main(String[] args) {
        Runnable runnable = new Test();
        Thread thread1 = new Thread(runnable);
        Thread thread2 = new Thread(runnable);
        Thread thread3 = new Thread(runnable);
        Thread thread4 = new Thread(runnable);
        thread1.start();
        thread2.start();
        thread3.start();
        thread4.start();
    }
}

因为sleep不会释放对象锁,即使当前线程休眠了,其他线程也无法拿到该runable对象,当该线程休眠结束后,继续执行;所以该结果图:
可见,在Thread-0运行时,调用了sleep,但其他线程无法拿到锁对象;
在这里插入图片描述
2、线程让步 yield()
暂停当前正在执行的线程对象,并执行其他线程(只能让拥有相同优先级的线程获取CPU)
当前线程不会立即交出CPU,交出时间由系统调度
同样不会释放对象锁,即使当前持有某个对象的的线程调用yield方法让步了,其他线程也无法持有该对象,等让步结束后,继续该线程的执行;

public class Test2  implements  Runnable{
    @Override
    public synchronized void run() {
        for(int i=0;i<5;i++) {
            Thread.yield();//不会释放对象锁
            System.out.println(Thread.currentThread().getName()+"="+i);
        }
    }
    public static void main(String[] args) {

        Runnable runnable=new Test2();

        Thread thread1=new Thread(runnable,"线程1");
        Thread thread2=new Thread(runnable,"线程2");
        Thread thread3=new Thread(runnable,"线程3");
        thread1.start();
        thread2.start();
        thread3.start();
    }

}

结果:
因为不会释放对象锁,即使当前持有某个对象的的线程调用yield方法让步了,其他线程也无法持有该对象,等让步结束后,继续该线程的执行;
在这里插入图片描述
由图可知:线程1完全执行完毕之后,另一个线程才开始执行;在线程1运行的过程中,在线程中调用了yield方法,线程1让步了,但其他线程拿不到这个对象锁,可见yield不会释放对象锁;

3、线程等待 join()
若一个线程1需要等待另一个线程2执行完毕后再恢复执行,可以在线程1中调用线程2的join()方法 ,会释放对象锁

public class Test2 {
    public static void main(String[] args) {
        try {
            System.out.println("主线程开始");
            Runnable runnable=new MySleepTest();
            
            Thread thread1=new Thread(runnable);
            
            thread1.start();
            //线程等待,
            thread1.join();
            System.out.println("主线程执行完毕");
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

在这里插入图片描述
4、线程停止
1 设置标志位(无法处理线程阻塞时停止的问题)

    class MyStopThread implements Runnable{
   //设置标志位
    private  boolean flag=true;
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
    @Override
    public void run() {
        int i=0;
        while(flag){//flag为true时
            System.out.println(Thread.currentThread().getName()+",i="+i);
            i++;
        }
        //标志位flag一旦变为false,就输出该句
        System.out.println("线程停止");
    }
}
public class Test{
    public static void main(String[] args) {
        MyStopThread runnable=new MyStopThread();
        Thread thread=new Thread(runnable);
        thread.start();
        
        //让线程启动1S以后关闭
        
        try {
            //让主线程休眠1S
            thread.sleep(1000);
            //然后使标志位变为false
            runnable.setFlag(false);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2.调用Thread类提供的stop方法强行关闭线程, 本方法现在已经不推荐使用,因为会产生不完整数
因为是强行关闭,所以可能导致执行到一半就结束了,导致数据变化不一致。
3.调用Thread类提供的interrupt()方法:
A.若线程中没有使用类似sleep、wait、join时,调用此线程对象的interrupt方法并不会真正中断线程,只是简单地将线程的状态置为interrupt而已,我们可以根据此状态来进一步确定如何处理线程

class MyThread implements Runnable {
    private boolean flag = true;
    public void setFlag(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        int i = 0;
        while (flag) {
            boolean bool=Thread.currentThread().isInterrupted();//取得线程的状态
            if(bool){
                //一旦线程的状态有false变为true,就return结束该线程
                System.out.println("线程已被置为中断状态");
                return;
            }
            System.out.println("当前线程状态为:"+bool);
            System.out.println(Thread.currentThread().getName() + ",i=" + i);
            i++;
        }
        System.out.println("线程停止");
    }
}

public class Test4 {

    public static void main(String[] args) {
        MyThread runnable=new MyThread();
        Thread thread=new Thread(runnable);
        thread.start();
        try {
            Thread.sleep(1000);
            thread.interrupt();//若线程中没有使用类似sleep、wait、join时,只是改变线程的状态,改为true
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

B.若线程中调用了阻塞线程的方法,如:sleep(),wait(),join()
此时再调用线程的interrupt方法会抛出异常InterruptedException , 同时将线程状态还原(isInterrupted=false)

class MyTest implements Runnable {
    private boolean flag = true;
    public void setFlag(boolean flag) {
        this.flag = flag;
    }
    @Override
    public void run() {
        int i = 0;
        while (flag) {
            try {
                Thread.sleep(200);
                 /* boolean bool=Thread.currentThread().isInterrupted();
                 if(bool){  //可以发现bool一直为false
                     System.out.println("线程已被置为中断状态");
                     return;
                 }
                 System.out.println("当前线程状态为:"+bool);
                 System.out.println(Thread.currentThread().getName() + ",i=" + i);
                 i++;*/
            } catch (InterruptedException e) {
              
                //再catch中return,结束
                System.out.println("抛出中断异常");
                return;//终止
            }

        }
        System.out.println("线程停止");
    }
}

public class Test {
    public static void main(String[] args) {
        MyTest runnable=new MyTest();
        Thread thread=new Thread(runnable);
        thread.start();
        try {
            Thread.sleep(1000);//线程休眠
            thread.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值