美文网首页
多线程_2_停止和暂停

多线程_2_停止和暂停

作者: mm_cuckoo | 来源:发表于2018-03-08 19:54 被阅读23次

线程停止

停止线程是在多线程开发时很重要的技术点,掌握线程停止技术可以对线程的停止进行有效的处理。

停止线程的方法

在Java 中有3种方法可以终止正在运行的线程:

  1. 使用退出标志,使线程正常退出,使run方法执行完后线程终止。
  2. 使用stop方法强制终止相册,但是不推荐使用这个方法,因为stop和suspend及resume一样,都是废弃过期的方法,不推荐使用,如果使用可能产生不可预料的结果。
  3. 使用interrupt方法中断线程。

interrupt 停止线程

调用interrupt() 方法仅仅是在当前线程中打了一个停止的标记,并不是真的停只线程。
如下示例:

public class MyThead extends Thread {
    @Override
    public void run() {
        
        for (int i = 0; i < 100; i ++) {
            System.out.println("Thread num i:" + i);
        }
    }
}

public class ThreadMain {
    public static void main(String[] args) {
        MyThead thead = new MyThead();
        thead.start();
        thead.interrupt();
    }
}

最后在介绍连个方法:

  1. this.interrupted();
    说明:测试氮气线程是否已经是中断状态,执行后具有将状态标志置清除为false的功能。
  2. this.isInterrupted();
    说明:测试线程Thread对象是否已经是中断状态,但是不清除状态标志。
通过调用interrupt() 方法进行“停止”线程

示例代码如下:

public class MyThead extends Thread {
    @Override
    public void run() {
        
        for (int i = 0; i < 1000000; i ++) {
            if (this.interrupted()) {
                System.out.println("跳出了for循环.......");
                break;
            }
            System.out.println("Thread num i:" + i);
        }
    }
}

public class ThreadMain {
    public static void main(String[] args) {
        try {
            MyThead thead = new MyThead();
            thead.start();
            Thread.sleep(10);
            thead.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        
    }
}

通过上面的方法可以结束for循环,但是如果for循环后面还有代码,就要继续执行后面的代码,也就是说没有停止线程。使用要根据具体情况进行选择使用,

使用异常停止线程

这种方法是在线程运行时,在要停止线程时抛出一个异常,使线程被迫停止。
示例代码:

public class MyThead extends Thread {
    @Override
    public void run() {
        try {
            for (int i = 0; i < 1000000; i ++) {
                if (this.interrupted()) {
                    System.out.println("跳出了for循环.......");
                    throw  new InterruptedException("");
                }
                System.out.println("Thread num i:" + i);
            }
            System.out.println("我还没有结束,我还在运行哦........");
        }catch (InterruptedException e) {
            System.out.println("线程结束了");
        }
    }
}

public class ThreadMain {
    public static void main(String[] args) {
        try {
            MyThead thead = new MyThead();
            thead.start();
            Thread.sleep(10);
            thead.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

说明:

  1. 将所有需要在线程中运行的的代码放在try catch中,当想要结束线程运行的时候抛出个异常就可以了。
    2.如果线程正在运行,并且在sleep状态下,通过异常方法停止线程会清除停止状态值,使之成为false(指的是interrupt 的值);
  2. 只要sleep调用interrupt() 方法就会有异常抛出。

使用return 和 interrupt 结合停止线程

示例代码:

public class MyThead extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 1000000; i ++) {
            if (this.interrupted()) {
                System.out.println("线程要结束啦......");
                return;
            }
            System.out.println("Thread num i:" + i);
        }
        System.out.println("我还没有结束,我还在运行哦........");
    }
}

public class ThreadMain {
    public static void main(String[] args) {
        try {
            MyThead thead = new MyThead();
            thead.start();
            Thread.sleep(10);
            thead.interrupt();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
       
    }
}

线程暂停

线程暂停意味着此线程还可以继续运行。

suspend 和resume 方法

示例代码:

public class MyThead extends Thread {
    @Override
    public void run() {
        try {
            for (int i = 0; i < 1000; i ++) {
            Thread.sleep(1000);
            System.out.println("Thread num i:" + i);
            }
            System.out.println("线程结束了........");  
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

public class ThreadMain {
    public static void main(String[] args) {
        
        try {
            MyThead thead = new MyThead();
            thead.start();
            Thread.sleep(2000);
            thead.suspend();
            
            Thread.sleep(5000);
            thead.resume();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

上面是线程暂停的方法,但是,但是,注意,注意,这两个方法已经被弃用了。
下面说一下使用这两个方法的缺点:

  1. 线程独占
    如果使用不当,极容易造成公共的同步对象独占,使得其他线程无法访问公共同步对象。
    下面写一个简单例子理解一下:
public class MyObject {
    private int sign;
    public void setSign(int sign) {
        this.sign = sign;
    }
    
    public synchronized void putString() {
        if (sign == 1) {
            System.out.println("开始 suspend ");
            Thread.currentThread().suspend();
            System.out.println("结束suspend ");
        }
    }
}

public class ThreadMain {
    public static void main(String[] args) {
        try {
            MyObject object = new MyObject();
            object.setSign(1);

            Thread thread1 = new Thread(new Runnable() {
                @Override
                public void run() {
                    object.putString();
                }
            });
            thread1.start();

            Thread.sleep(3000);

            object.setSign(2);
            Thread thread2 = new Thread(new Runnable() {
                @Override
                public void run() {
                    object.putString();
                }
            });
            thread2.start();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

上面被线程1独占了,所以后面的线程都阻塞住了。

  1. 数据不同步:这里就不举例子了,挺好理解的。

介绍一个方法

yield() 方法:

yield() 方法的作用是放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间,但放弃的时间不确定,有可能刚刚放弃,马上又获得CPU时间片。

相关文章

网友评论

      本文标题:多线程_2_停止和暂停

      本文链接:https://www.haomeiwen.com/subject/sctufftx.html