精华内容
下载资源
问答
  • Java中终止线程的方式主要有三种:1、使用stop()方法,已被弃用。原因是:stop()是立即终止,会导致一些数据被到处理一部分就会被终止,而用户并不知道哪些数据被处理,哪些没有被处理,产生了不完整的“残疾”数据...

    Java中终止线程的方式主要有三种:

    1、使用stop()方法,已被弃用。原因是:stop()是立即终止,会导致一些数据被到处理一部分就会被终止,而用户并不知道哪些数据被处理,哪些没有被处理,产生了不完整的“残疾”数据,不符合完整性,所以被废弃。So, forget it!

    2、使用volatile标志位

    看一个简单的例子:

    首先,实现一个Runnable接口,在其中定义volatile标志位,在run()方法中使用标志位控制程序运行

    public class MyRunnable implements Runnable {

    //定义退出标志,true会一直执行,false会退出循环

    //使用volatile目的是保证可见性,一处修改了标志,处处都要去主存读取新的值,而不是使用缓存

    public volatile boolean flag = true;

    public void run() {

    System.out.println("第" + Thread.currentThread().getName() + "个线程创建");

    try {

    Thread.sleep(1000L);

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    //退出标志生效位置

    while (flag) {

    }

    System.out.println("第" + Thread.currentThread().getName() + "个线程终止");

    }

    }

    然后,在main()方法中创建线程,在合适的时候,修改标志位,终止运行中的线程。

    public class TreadTest {

    public static void main(String[] arg) throws InterruptedException {

    MyRunnable runnable = new MyRunnable();

    //创建3个线程

    for (int i = 1; i <= 3; i++) {

    Thread thread = new Thread(runnable, i + "");

    thread.start();

    }

    //线程休眠

    Thread.sleep(2000L);

    System.out.println("——————————————————————————");

    //修改退出标志,使线程终止

    runnable.flag = false;

    }

    }

    最后,运行结果,如下:

    第1个线程创建

    第2个线程创建

    第3个线程创建

    --------------------------

    第3个线程终止

    第1个线程终止

    第2个线程终止

    3、使用interrupt()中断的方式,注意使用interrupt()方法中断正在运行中的线程只会修改中断状态位,可以通过isInterrupted()判断。如果使用interrupt()方法中断阻塞中的线程,那么就会抛出InterruptedException异常,可以通过catch捕获异常,然后进行处理后终止线程。有些情况,我们不能判断线程的状态,所以使用interrupt()方法时一定要慎重考虑。

    第一种:正在运行中终止

    public class MyThread extends Thread {

    public void run(){

    super.run();

    try {

    for(int i=0; i<500000; i++){

    if(this.interrupted()) {

    System.out.println("线程已经终止, for循环不再执行");

    throw new InterruptedException();

    }

    System.out.println("i="+(i+1));

    }

    System.out.println("这是for循环外面的语句,也会被执行");

    } catch (InterruptedException e) {

    System.out.println("进入MyThread.java类中的catch了。。。");

    e.printStackTrace();

    }

    }

    }

    public class Run {

    public static void main(String args[]){

    Thread thread = new MyThread();

    thread.start();

    try {

    Thread.sleep(2000);

    thread.interrupt();

    } catch (InterruptedException e) {

    e.printStackTrace();

    }

    }

    }

    运行结果如下:

    ...

    i=203798

    i=203799

    i=203800

    线程已经终止, for循环不再执行

    进入MyThread.java类中的catch了。。。

    java.lang.InterruptedException

    at thread.MyThread.run(MyThread.java:13)

    第二种:阻塞状态(sleep,wait等)终止

    public class MyThread extends Thread {

    public void run(){

    super.run();

    try {

    System.out.println("线程开始。。。");

    Thread.sleep(200000);

    System.out.println("线程结束。");

    } catch (InterruptedException e) {

    System.out.println("在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:" + this.isInterrupted());

    e.printStackTrace();

    }

    }

    }

    线程开始。。。

    在沉睡中被停止, 进入catch, 调用isInterrupted()方法的结果是:false

    java.lang.InterruptedException: sleep interrupted

    at java.lang.Thread.sleep(Native Method)

    at thread.MyThread.run(MyThread.java:12)

    从打印的结果来看, 如果在sleep状态下停止某一线程,会进入catch语句,并且清除停止状态值,使之变为false。

    前一个实验是先sleep然后再用interrupt()停止,与之相反的操作在学习过程中也要注意:

    public class MyThread extends Thread {

    public void run(){

    super.run();

    try {

    System.out.println("线程开始。。。");

    for(int i=0; i<10000; i++){

    System.out.println("i=" + i);

    }

    Thread.sleep(200000);

    System.out.println("线程结束。");

    } catch (InterruptedException e) {

    System.out.println("先停止,再遇到sleep,进入catch异常");

    e.printStackTrace();

    }

    }

    }

    public class Run {

    public static void main(String args[]){

    Thread thread = new MyThread();

    thread.start();

    thread.interrupt();

    }

    }

    运行结果:

    i=9998

    i=9999

    先停止,再遇到sleep,进入catch异常

    java.lang.InterruptedException: sleep interrupted

    at java.lang.Thread.sleep(Native Method)

    at thread.MyThread.run(MyThread.java:15)

    感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

    展开全文
  • RunnableupdateThread=newRunnable(){inti=0;publicvoidrun(){System.out.println(...//得到一个消息对象,Message类是由Android操作系统提供Messagemsg=updateBa...Runnable updateThread = new Runnable(){ int i...

    RunnableupdateThread=newRunnable(){inti=0;publicvoidrun(){System.out.println("BeginThread");i=i+10;//得到一个消息对象,Message类是由Android操作系统提供Messagemsg=updateBa...

    Runnable updateThread = new Runnable(){ int i = 0; public void run() { System.out.println("Begin Thread"); i = i + 10; //得到一个消息对象,Message类是由Android操作系统提供 Message msg = updateBarHandler.obtainMessage(); //将msg对象的arg1参数的值设置为i,用arg1和arg2这两个长远变量传递消息,优点是系统性能消耗较小 msg.arg1 = i; try{ Thread.sleep(1000); } catch(InterruptedException e){ e.printStackTrace(); } //(3)执行sendMessage方法将消息压入到消息队列中去,而不等消息被处理,sendMessage马上返回,继续向下执行。 updateBarHandler.sendMessage(msg); if(i == 100){ System.out.println("over100!"); //(7)直到i的值为100时,就将线程对象从handler当中移除。调用removaCallbacks方法把updateThread从handler当中去除掉,这个线程将不再执行,就此停止。 updateBarHandler.removeCallbacks(updateThread); System.out.println("removeCallbacks--->updateThread!"); } } }; 高手帮忙看下上面的代码,其实就是用Handler来实现进度条的进度啦,而在运行的时候,进度条是运行了,但我看到LogCat里面的信息发现,Runnable里面的run方法一直在运行打印"Begin Thread",并没有停下来?想知道为什么我已经调用了removeCallbacks,run方法还是运行,还有什么方法可以调用把它停下来吗??

    展开

    展开全文
  • Java 中线程的生命周期中一共有 6 种状态:New(新创建)Runnable(可运行)Blocked(被阻塞)Waiting(等待)Timed Waiting(计时等待)Terminated(被终止)查看 Thread 类的源码时,内部还定义了这样一个枚举类。...

    线程有哪 6 种状态?

    人有生老病死。同样的,线程有自己的生命周期。在 Java 中线程的生命周期中一共有 6 种状态:New(新创建)

    Runnable(可运行)

    Blocked(被阻塞)

    Waiting(等待)

    Timed Waiting(计时等待)

    Terminated(被终止)

    查看 Thread 类的源码时,内部还定义了这样一个枚举类。这个枚举类定义的就是线程的状态,源码如下:

    public enum State {

    NEW,

    RUNNABLE,

    BLOCKED,

    WAITING,

    TIMED_WAITING,

    TERMINATED;

    }

    PS:线程在任何时刻只可能处于以上 6 种的其中 1 种状态,我们可以调用 getState () 查看线程的状态。

    线程是如何切换状态的?

    我们知道线程有 6 种状态。然而,它是如何切换的呢?狗哥根据自己的理解做了一张图,接下来将根据这张图详细了解下线程状态的切换。

    线程的 6 种状态

    NEW (新创建)

    先注意 NEW 状态:线程被 NEW 出来,但还没调用 start 方法时,就处于这种状态。一旦调用了 start 方法也就进入了 RUNNABLE 状态。

    RUNNABLE(可运行)

    处于 RUNNABLE 的线程,比较特殊。它还分两种状态:Running 和 Ready。也就是说,Java 中处于 Runnable 状态的线程有可能正在执行,也有可能没有正在执行,正在等待被分配 CPU 资源。

    因此,我们可以推断出,一个处于 Runnable 状态的线程,当它运行到任务的一半时,执行该线程的 CPU 被调度去做其他事情,则该线程暂时不运行。但是,它的状态依然不变,还是 Runnable,因为它有可能随时被调度回来继续执行任务。

    也就是说:处于 Runnable 状态的线程并不一定在运行。这点在面试中常问,小伙伴们要注意了。

    Blocked(被阻塞)

    再来看看最简单的 Blocked 状态,从 Runnable 进入 Blocked 只有一种可能:就是进入 synchronized 关键字保护的代码,但是没有获取到 monitor 锁。

    线程的 6 种状态

    再来,看图的右侧,Blocked ----> Runnable 状态:当处于 Blocked 状态的线程获取到锁。

    Waiting (等待)

    线程从 Runnable 进入 Blocked 状态,有三种可能性:没有设置 Timeout 参数的 Object.wait () 方法。

    没有设置 Timeout 参数的 Thread.join () 方法。

    LockSupport.park () 方法。

    上面我们知道,线程进入 Blocked 状态只可能是:进入 synchronized 保护的代码,但是没获取到 monitor 锁。然而,Java 中还有很多锁,比如:ReentrantLock。线程在获取这种锁时,没有抢到就会进入 Waiting 状态,因为它本质上是调用了 LockSupport.park () 方法。

    同样的,调用 Object.wait () 和 Thread.join () 也会让线程进入等待状态。

    Blocked 与 Waiting 的区别是:Blocked 在等待其他线程释放 monitor 锁,而 Waiting 则是在等待某个条件,比如 join 的线程执行完毕,或者是 notify ()/notifyAll ()。

    线程的 6 种状态

    看 Waiting 右侧,Waiting ----> Runnable:1、当执行了 LockSupport.unpark (),2、join 的线程运行结束,3、被中断

    看 Waiting 右侧,Waiting ----> Blocked:我们看图可以知道其他线程调用 notify () 或 notifyAll () 来唤醒处于 Waiting 的线程,它会直接进入 Blocked 状态。这是为什么?

    其他线程能调用 notify () 或 notifyAll () 试图唤醒 Waiting 状态线程,说明必须持有同一个 monitor 锁,也就是说处于 Waiting 的线程被唤醒后并不能马上抢到 monitor 锁,所以它必须先进入 Blocked 状态。而唤醒它的线程执行完毕释放锁后,它能抢到锁就从 Blocked 进入 Runnable 状态。

    Timed Waiting(计时等待)

    这种状态与 Waiting 状态的区别在于:有没有时间限制,Timed Waiting 会等待超时,由系统自动唤醒,或者在超时前被唤醒信号唤醒。

    有以下 5 种情况会让线程进入 Timed Waiting 状态:设置 Timeout 参数的 Thread.sleep (time) 方法。

    设置 Timeout 参数的 Object.wait (time) 方法。

    设置 Timeout 参数的 Thread.join (time) 方法。

    设置 Timeout 参数的 LockSupport.parkNanos (long nanos) 方法。

    设置 Timeout 参数的 LockSupport.parkUntil (long deadline) 方法。

    线程的 6 种状态

    看 Timed Waiting 右侧,Timed Waiting ----> Blocked:跟 Waiting 一样,其他线程执行 notify () 和 notifyAll (),当前线程也是先进入 Blocked 状态,而后视锁的获取情况再决定是否进入 Runnable 状态。

    另外,Timed Waiting ----> Runnable :1、当前线程的超时时间到了且能直接获取到锁,2、join 的线程运行结束,3、被中断,4、调用了 LockSupport.unpark (),这几种情况会直接恢复到 Runnable,而无需经历 Blocked 状态。

    Terminated(被终止)

    最后一种,想要进入终止状态就比较简单了,有三种情况:任务执行完毕,线程正常退出。

    出现一个没有捕获的异常(比如直接调用 interrupt () 方法)。

    总结线程的状态是需要按照箭头方向走,比如线程从 New 状态是不可以直接进入 Blocked 状态的,它需要先经历 Runnable 状态。

    线程生命周期不可逆:一旦进入 Runnable 状态就不能回到 New 状态;一旦被终止就不可能再有任何状态的变化。所以一个线程只能有一次 New 和 Terminated 状态,只有处于中间状态才可以相互转换。

    展开全文
  • 情况我有一个Runnable。我有一个类,计划这个Runnable执行使用一个ScheduledExecutorService与scheduleWithFixedDelay。目标我想改变这个类来调度Runnable的固定延迟执行无限期,或者直到它已经运行了一定次数,这取...

    情况

    我有一个Runnable。我有一个类,计划这个Runnable执行使用一个ScheduledExecutorService与scheduleWithFixedDelay。

    目标

    我想改变这个类来调度Runnable的固定延迟执行无限期,或者直到它已经运行了一定次数,这取决于传递给构造函数的一些参数。

    如果可能,我想使用相同的Runnable,因为它在概念上是相同的事情,应该是“运行”。

    可能的方法

    方法#1

    有两个Runnables,一个在一些执行(它保持计数)和一个不执行之后取消计划:

    public class MyClass{

    private ScheduledExecutorService scheduler = Executors.newSingleThreadScheduledExecutor();

    public enum Mode{

    INDEFINITE, FIXED_NO_OF_TIMES

    }

    public MyClass(Mode mode){

    if(mode == Mode.INDEFINITE){

    scheduler.scheduleWithFixedDelay(new DoSomethingTask(), 0, 100, TimeUnit.MILLISECONDS);

    }else if(mode == Mode.FIXED_NO_OF_TIMES){

    scheduler.scheduleWithFixedDelay(new DoSomethingNTimesTask(), 0, 100, TimeUnit.MILLISECONDS);

    }

    }

    private class DoSomethingTask implements Runnable{

    @Override

    public void run(){

    doSomething();

    }

    }

    private class DoSomethingNTimesTask implements Runnable{

    private int count = 0;

    @Override

    public void run(){

    doSomething();

    count++;

    if(count > 42){

    // Cancel the scheduling.

    // Can you do this inside the run method, presumably using

    // the Future returned by the schedule method? Is it a good idea?

    }

    }

    }

    private void doSomething(){

    // do something

    }

    }

    我宁愿只有一个Runnable执行doSomething方法。将调度绑定到Runnable感觉错了。你怎么看待这件事?

    方法#2

    有一个Runnable用于执行我们要定期运行的代码。有一个单独的计划运行,检查第一个Runnable运行了多少次,并取消到一定量。这可能不准确,因为它将是异步的。这感觉有点麻烦。你怎么看待这件事?

    方法3

    扩展ScheduledExecutorService并添加一个方法“scheduleWithFixedDelayNTimes”。也许这样的类已经存在了?目前,我使用Executors.newSingleThreadScheduledExecutor();以获取我的ScheduledExecutorService实例。我估计必须实现类似的功能来实例化扩展的ScheduledExecutorService。这可能是棘手的。你怎么看待这件事?

    无调度器方法[编辑]

    我不能使用调度程序。我可以改为:

    for(int i = 0; i < numTimesToRun; i++){

    doSomething();

    Thread.sleep(delay);

    }

    并在某些线程运行。你觉得怎么样?您可以仍然使用runnable并直接调用run方法。

    任何建议欢迎。我正在寻找一个辩论,找到“最佳实践”的方式来实现我的目标。

    展开全文
  • Java程序如何停止一个线程?建议使用”异常法”来终止线程的继续运行。在想要被中断执行的线程中, 调用 interrupted()方法,该方法用来检验当前线程是否已经被中断,即该线程 是否被打上了中断的标记,并不会使得线程...
  • 我有一个线程正在运行,但从外面我不能绕过一个值来停止该线程.如何在Mytest()中发送false / true值或调用运行的线程公共方法?当我按下按钮1?例如:thread.interrupt(); runnable.stop();或runnable.start();// ...
  • 实现Runnable接口: 3.sleep和wait的区别: (1)来自这篇博文:http://blog.csdn.net/darrenmu/article/details/21243035 大意如下: sleep(100):保持对象锁,仍然占有该锁; wait(100):释放对象锁。 (2)附sleep()...
  • 我在以下程序中使用处理程序,我想在i = 5时停止它,但处理程序不会停止并连续运行。b1.setOnClickListener(new OnClickListener() {public void onClick(View v) {handler = new Handler();runnable = new Runnable...
  • Java程序如何停止一个线程?建议使用”异常法”来终止线程的继续运行。在想要被中断执行的线程中, 调用 interrupted()方法,该方法用来检验当前线程是否已经被中断,即该线程 是否被打上了中断的标记,并不会使得线程立...
  • 我试图通过调用Thread类的sleep()方法暂停执行部分程序几...例如,如果我有代码:Thread compoundThread = new Thread(new Runnable(){public void run(){try{Thread.currentThread().sleep(2000);}catch (Interrupt...
  • Runnable是执行工作的独立任务,但是不具有任何返回值。 Runnable 接口应该由那些打算通过某一线程执行其实例的类...激活的意思是说某个线程已启动并且尚未停止。此外,Runnable 为非 Thread 子类的类提供了一种激活
  • package java.lang; /** * Runnable接口应该由,实例要由线程执行的类,来实现。 * 类必须定义一个名为run的无参数方法。 * * <p> * 该接口旨在为那些希望在活动时执行代码的对象提供一个通用协议。 *...
  • JAVA 线程停止

    2021-03-06 21:38:58
    之前使用过sleep来停止线程 我们这次使用别的方法来停止线程 //测试线程停止 ...public class TestStop implements Runnable{ //设置一个标志位 private boolean flag = true; @Override public void run
  • 线程中断在Java中,停止一个线程的主要机制是中断,中断并不是强迫终止一个线程,它是一种协作机制,是给线程传递一个取消信号,但是由线程来决定如何以及何时退出。本节我们主要就是来理解Java的中断机制线程中断的...
  • Java如何停止线程

    千次阅读 2018-10-25 11:28:24
    Preface 启动一个线程或任务都是很简单,线程一般在任务结束后便会自行停止。...Java没有提供任何机制,来安全地强迫停止手头地工作。   一般来讲,对于Runnable来说,需要做的任务都是在run方法里面进行的,...
  • Java线程停止

    2018-11-26 19:20:29
    多线程中有三种方法可以停止线程 设置标记位,可以使线程正常退出 使用stop方法强制使线程退出,但是这个方法不太安全已经被废弃 使用Thread类中的一个interrupt()可以中断线程 标记位 举例: class MyThread ...
  • java 线程停止

    2021-02-22 19:49:41
    public class TestStop implements Runnable { private boolean flag=true; public void run() { // TODO Auto-generated method stub int i=0; while(flag) { System.out.println("run..thread "+i+...
  • 本文主要介绍如何开始创建线程以及管理线程池,在 Java 语言中,一个最简单的线程如下代码所示:Runnable runnable = new Runnable(){public void run(){System.out.println("Run");}}可通过下面一行代码来启动这个...
  • Runnable Runnable 是一个接口,是线程的执行体。...场景2:优雅的停止线程。 获取线程(执行体)的执行结果 注意 本文中的执行体可能是Runnable 中的run方法或者Callable中的Call方法。线程的执行结
  • Java线程就像一个虚拟CPU,可以在Java应用程序中执行Java代码。当Java应用程序启动时,它的main()方法由主线程执行,主线程是Java虚拟机为运行应用程序而创建的一个特殊线程。你可在应用程序内部创建和启动更多的...
  • java线程停止之interrupt

    2020-05-17 13:58:07
    今天笔者学习了中断线程...public class InterruptDemo02 implements Runnable{ @Override public void run() { while(!Thread.currentThread().isInterrupted()){ //false try { TimeUnit.SECONDS.sleep(200);
  • 以下代码是我的应用程序中的服务器代码:private int serverPort;private Thread serverThread = null;public void networkListen(int ...if (serverThread == null){Runnable serverRunnable = new ServerRunnabl...
  • 为什么我的线程无法停止???class Threadz {class runP implements Runnable {int num;private volatile boolean exit = false;Thread t;public runP() {t = new Thread(this, "T1");t.start();}@Overridepublic void...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 672
精华内容 268
热门标签
关键字:

javarunnable停止

java 订阅