Java 线程停止

Java 线程停止的方法有三种目前学习到的。

  1. stop 方法。
  2. volatile 变量控制退出。
  3. interrupt 方法。

第一种方法官方不建议,这种停止方法会导致释放锁后线程工作来不及清理,从而会出现数据不一致。

第二种方法写了个代码学习,如下:

共享资源类:
package com.lenovo.plm.dms.p6;


public class Service {
    
    private volatile boolean requestedStoppedFlag = false;
    
    private long record;
    
    private String lock = new String();
    
    public Service(long record){
        this.record = record;
    }
    
    public void execute(){


        synchronized (lock) {
            while(true){
                if(requestedStoppedFlag){
                    return;
                }
                System.out.println(Thread.currentThread().getName() + " " +record++);
            }
            
        }
    }
    public void stop(){
        
        synchronized(this){
            requestedStoppedFlag = true;
            System.out.println(Thread.currentThread().getName() + " " +record++);
        }
    }
}

线程类:
package com.lenovo.plm.dms.p6;


public class MyThread extends Thread {


    
    private Service service;
    
    public MyThread(Service service){
        this.service = service;
    }
    
    @Override
    public void run() {
       service.execute();
    }
}

执行类如下:

package com.lenovo.plm.dms.p6;


public class Main {
    
    public static void main(String[] args) {
        
        Service service = new Service(0);
        
        MyThread t1 = new MyThread(service);
        t1.start();
       
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        service.stop();
    }
}


这里创建了两个线程并发执行。主线程等待3s后,执行停止方法。执行后,线程结束。



第三种方法是用interrupt。见代码。
先创建service 共享资源的类。
package com.lenovo.plm.dms.p7;

public class Service {
    
    private long record;
    private String lock = new String();
    
    public Service(long record){
        this.record = record;
    }

    public void execute(){
        
        synchronized(lock){            
            while(true){
                if(Thread.interrupted()){
                    return;
                }
                System.out.println(Thread.currentThread().getName() + " " + record++);
            }
        }
    }  
}

其次线程类
package com.lenovo.plm.dms.p7;

public class MyThread extends Thread {

    private Service service;
    
    public MyThread(Service service){
        this.service = service;
    }
    
    @Override
    public void run() {
        // TODO Auto-generated method stub
        super.run();
        service.execute();
    }
    
}


最后调用:

package com.lenovo.plm.dms.p7;

public class Main {
    
    public static void main(String[] args) {
        
        Service service = new Service(0);
        MyThread t = new MyThread(service);
        t.start();
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        t.interrupt();
        
        try {
            t.join();
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        
        System.out.println(t.isAlive());
        
    }
}

执行结果是线程被停止了。



这三种方法理解如下:
第一种跳过。
第二种使用了volatile关键字,这个关键字可以保证线程每次读取该变量时,都是直接从主内存中读取,不会直接读线程内存中的值。这样,可以确保线程每次读到的值,都是最新的。因此有线程修改了这个变量,那么
当前执行的线程会马上知道,因此可以作为线程间通信的方法。

第三种使用了线程自身的方法来检查中断状态位。




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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值