java里如何结束一个进程

163 阅读2分钟

1、线程结束的方法

1). 自然结束(能自然结束就尽量自然结束)

2). stop() suspend() resume() (不推荐)

需要注意的是,直接调用线程的stop()方法已被废弃,不推荐使用,因为它可能会导致线程不可预料的状态和资源泄露。

3). volatile标志

  1. 不适合某些场景(比如还没有同步的时候,线程做了阻塞操作,没有办法循环回去)
  2. 打断时间也不是特别精确,比如一个阻塞容器,容量为5的时候结束生产者, 但是,由于volatile同步线程标志位的时间控制不是很精确,有可能生产者还继续生产一段儿时间

4). interrupt() and isInterrupted(比较优雅)

2、代码示例

1)、首先依然创建一个工具类,控制程序运行时间

public static class SleepHelper {
    public static void sleepSeconds(int seconds) {
        try {
            TimeUnit.SECONDS.sleep(seconds);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    public static void sleepMilli(int i) {
        try {
            TimeUnit.MILLISECONDS.sleep(i);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

2)、使用stop()结束进程

// =============================================
Thread t1 = new Thread( ()->{
    while (true){
        System.out.println("go on");
        SleepHelper.sleepSeconds(1);
    }
});
// 运行t1
t1.start();
// 等待5秒
SleepHelper.sleepSeconds(5);
// 直接结束t2
// 不推荐,因为会破坏程序的一致性,使程序进入死锁
t1.stop();

3)、使用suspend() resume()结束进程

// =============================================
Thread t2 = new Thread(()->{
    while (true){
        System.out.println("go on");
        SleepHelper.sleepSeconds(1);
    }
});
// 将t2运行
t2.start();
// 使t2运行5秒
SleepHelper.sleepSeconds(5);
// 再将t2停止
t2.suspend();
SleepHelper.sleepSeconds(3);
// 重新唤醒t2
// 不推荐,因为会破坏程序的一致性,使程序进入死锁
t2.resume();

4)、使用volatile标志

// =============================================

private static volatile boolean running = true;
Thread t3 = new Thread(() -> {
    long i = 0L;
    // 使用volatile标志位
    while (running) {
        //wait recv accept
        i++;
    }

    System.out.println("end and i = " + i);
});
t3.start();

SleepHelper.sleepSeconds(1);

running = false;

5)、使用interrupt() and isInterrupted()

// =============================================
Thread t4 = new Thread(() -> {
    while (!Thread.interrupted()) {
        //sleep wait
    }

    System.out.println("t1 end!");
});

t4.start();

SleepHelper.sleepSeconds(1);

t4.interrupt();

// =============================================
Thread t5 = new Thread(() -> {
    System.out.println("1");
    // 只有当线程结束的时候才会运行到下方输出2
    LockSupport.park();
    System.out.println("2");
});

t5.start();

SleepHelper.sleepSeconds(1);

t5.interrupt();

6)、整体代码

public static class SleepHelper {
        public static void sleepSeconds(int seconds) {
            try {
                TimeUnit.SECONDS.sleep(seconds);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }

        public static void sleepMilli(int i) {
            try {
                TimeUnit.MILLISECONDS.sleep(i);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private static volatile boolean running = true;

    public static void main(String[] args) throws Exception {

//        Solution solution = new Solution();

        // =============================================
        Thread t1 = new Thread( ()->{
            while (true){
                System.out.println("go on");
                SleepHelper.sleepSeconds(1);
            }
        });
        // 运行t1
        t1.start();
        // 等待5秒
        SleepHelper.sleepSeconds(5);
        // 直接结束t2
        // 不推荐,因为会破坏程序的一致性,使程序进入死锁
        t1.stop();

        // =============================================
        Thread t2 = new Thread(()->{
            while (true){
                System.out.println("go on");
                SleepHelper.sleepSeconds(1);
            }
        });
        // 将t2运行
        t2.start();
        // 使t2运行5秒
        SleepHelper.sleepSeconds(5);
        // 再将t2停止
        t2.suspend();
        SleepHelper.sleepSeconds(3);
        // 重新唤醒t2
        // 不推荐,因为会破坏程序的一致性,使程序进入死锁
        t2.resume();

        // =============================================
        Thread t3 = new Thread(() -> {
            long i = 0L;
            // 使用volatile标志位
            while (running) {
                //wait recv accept
                i++;
            }

            System.out.println("end and i = " + i);
        });
        t3.start();

        SleepHelper.sleepSeconds(1);

        running = false;

        // =============================================
        Thread t4 = new Thread(() -> {
            while (!Thread.interrupted()) {
                //sleep wait
            }

            System.out.println("t1 end!");
        });

        t4.start();

        SleepHelper.sleepSeconds(1);

        t4.interrupt();

        // =============================================
        Thread t5 = new Thread(() -> {
            System.out.println("1");
            // 只有当线程结束的时候才会运行到下方输出2
            LockSupport.park();
            System.out.println("2");
        });

        t5.start();

        SleepHelper.sleepSeconds(1);

        t5.interrupt();
    }