Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >话说 线程创建&启动&停止

话说 线程创建&启动&停止

原创
作者头像
木子的昼夜
修改于 2021-04-06 03:11:41
修改于 2021-04-06 03:11:41
1.2K0
举报

线程创建&启动&停止

线程啊是个好东西,但是平时工作很少自己创建线程,所以一些基础的操作可能就不容易记起来,这篇文章常看看有益身心健康

1. 创建
代码语言:txt
AI代码解释
复制
public class TestDeamon {
    public static void main(String[] args) {
        // lambda 表达式
        Thread t1 = new Thread(()->System.out.println("这是一个线程01!"));
        Thread t2 = new Thread(()->{
            System.out.println("这是一个线程02!");
        });
        // 匿名内部类
        Thread t3 = new Thread(){
            @Override
            public void run() {
                System.out.println("这是一个线程03!");
            }
        };
        // 继承Thread
        Thread t4 =new MyThread04();

        // 实现Runnable 参数是Runnable
        Thread t5 = new Thread(new MyRunnable());

        // 时效内
        // 启动线程
        t1.start();
        t2.start();
        t3.start();
        t4.start();
        t5.start();
    }
}

/**
 * 继承Thread
 * public class Thread implements Runnable
 * thread是实现了Runnable接口
 */
class MyThread04 extends  Thread{
    @Override
    public void run() {
        System.out.println("这是一个线程04!");
    }
}

/**
 * 实现Runnable
 */
class MyRunnable implements   Runnable{
    @Override
    public void run() {
        System.out.println("这是一个线程05!");
    }
}
2. 启动
代码语言:txt
AI代码解释
复制
// 启动线程
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
输出:
这是一个线程01!
这是一个线程02!
这是一个线程03!
这是一个线程04!
这是一个线程05!

线程启动之后就会执行run方法

3. 停止线程/中断
3.1. 线程执行完 自己结束

执行完for循环 自动结束

代码语言:txt
AI代码解释
复制
// lambda 表达式
        Thread t1 = new Thread(()->{
            for (int i = 0; i < 10; i++) {
                try{
                    Thread.sleep(1000);
                    System.out.println("===");
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
        t1.start();
3.2. stop 被废弃了

stop已经被废弃,stop太粗暴,不温柔,所以没人喜欢..

代码语言:txt
AI代码解释
复制
 // lambda 表达式
Thread t1 = new Thread(()->{
    for (;;) {
        try{
            Thread.sleep(1000);
            System.out.println("===");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
});
t1.start();
// 10秒后 停止
Thread.sleep(10000);
// 停止
t1.stop();

很容易产生数据不一致 因为某一个事务或者一块代码没执行完的时候 就有可能被干掉

举个例子:

代码语言:txt
AI代码解释
复制
// lambda 表达式
Thread t1 = new Thread(()->{
    System.out.println("对象去洗澡了");
    try{
        System.out.println("钻被窝等着...");
        Thread.sleep(10000);
        System.out.println("洗白白 开小会");
    } catch (Exception e) {
        e.printStackTrace();
    }
});

t1.start();
// 10秒后 停止
Thread.sleep(5000);
// 停止
t1.stop();

结果:
对象去洗澡了
钻被窝等着...
    
可以看到哈,你等了半天,还没开始开小会就被打断了 。。  
3.3 suspend resume 被废弃了

suspend 让线程暂停

resume 让暂停的线程继续执行

suspend容易产生死锁等问题 如果忘记resume或者resume异常 那如果suspend的线程持有锁的话,就死锁了

代码语言:txt
AI代码解释
复制
public class TestDeamon03 {
    // 锁  表示对象
    public static Object obj = new Object();
    public static void main(String[] args) throws InterruptedException {

        // lambda 表达式
        Thread t1 = new Thread(()->{
                synchronized (obj){
                   try {
                       System.out.println("我出去打工了 留对象在家");
                       Thread.sleep(10000);
                       System.out.println("我回来了 娶我对象 ");
                   } catch (Exception e) {
                       e.printStackTrace();
                   }
                }
        });

        t1.start();
        // 2秒后 暂停
        Thread.sleep(2000);
        // 暂停
        t1.suspend();
        Thread.sleep(2000);
		// 恢复 
        resumeObj(t1);
    }

    // resume 模拟异常
    static void resumeObj(Thread t){
        int i = 1/0;
        t.resume();
    }
}

你找了个对象,把人家放家里,说打工1年回来娶,然后你回家途中找了个别人,一起幸福生活了,你对象在家...

被你占用,你又不通知、不释放

3.4 volatile 结束

volatile(保证内存可见)修饰一个变量 时间可能控制不是很精确 因为volatile修改了之后刷新到内存 在另一个线程读取到 还是需要时间的 虽然很快 但是一般的情况 都没什么问题

代码语言:txt
AI代码解释
复制
public class TestDeamon04 {
    static volatile boolean flag = true;
    public static void main(String[] args) throws InterruptedException {
        // lambda 表达式
        Thread t1 = new Thread(()->{
            int count =0;
            // flag == true 循环   flag==false 停止循环 也就结束线程了
            while (flag) {
                try {
                    Thread.sleep(1);
                    count++;
                } catch (Exception e){
                    e.printStackTrace();
                }
            }
            System.out.println("count:"+count);
        });

        t1.start();
        // 1秒后 停止
        Thread.sleep(1000);
        flag = false;
    }
}

多次输出结果:
    505、525、507、512 
可以看到每次输出结果是不确定的 ,
这种方式只能保证到达某个条件了就停止线程  
但是不能控制线程准确点停止 
比如你想让一个线程循环100次就停止 很难准确控制
3.5 interrupt 结束

也算标志位 但是比volatile高级一点 比如sleep、wait等操作会被中断

代码语言:txt
AI代码解释
复制
// lambda 表达式
final Thread t1 = new Thread(()->{
    int count =0;
    //
    while (!Thread.interrupted()) {
        try {
            count++;
        } catch (Exception e){
            e.printStackTrace();
        }
    }
    System.out.println("count:"+count);
});

t1.start();
// 1秒后 停止
Thread.sleep(1000);
t1.interrupt();

中断sleep测试:interrupt会中断sleep在异常捕获里边break就行了 而标志位flag是无法做到的

代码语言:txt
AI代码解释
复制
public class TestDeamon06 {
    static volatile boolean flag = true;
    public static void main(String[] args) throws InterruptedException {
        // lambda 表达式
        final Thread t1 = new Thread(()->{
            //
            while (!Thread.interrupted()) {
                try {
                    Thread.sleep(20000000);
                } catch (Exception e){
                    break;
                }
            }
            System.out.println("interrupted 结束 ");
        });

        // lambda 表达式
        final Thread t2 = new Thread(()->{
            while (flag) {
                try {
                    Thread.sleep(20000000);
                } catch (Exception e){
                    break;
                }
            }
            System.out.println("volatile-结束");
        });

        t1.start();
        t2.start();
        // 1秒后 停止
        Thread.sleep(1000);
        t1.interrupt();
        flag = false;
    }
}

总结:

stop 、suspend resume 已废弃

volatile标志位 无法中断sleep wait 等操作

interrupt 相当于标志位但是可以中断sleep wait等操作 捕获InterruptedException异常 进行线程结束

可能还有其他方式 大多数是基于标志位的

欢迎关注公众号:

公众号二维码.jpg
公众号二维码.jpg

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
线程,JVM锁整理
首先wait()和notify(),notifyAll()方法一定是一般对象方法,他们并不属于线程对象方法,一定是跟synchronized(监视器锁)结伴出现的。wait()方法执行时会释放获取的监视器锁,线程进入休眠等待状态。而notify()执行时,会随机唤醒一个等待状态的线程,并重新获取监视器锁,然后再继续执行。notifyAll()方法是唤醒所有的相同对象的等待线程,再去竞争获取监视器锁。
算法之名
2019/08/20
9460
为什么不推荐使用 stop、suspend 方法中断线程?
我们知道像stop、suspend这几种中断或者阻塞线程的方法在较高java版本中已经被标记上了@Deprecated过期标签,那么为什么她们曾经登上了java的历史舞台而又渐渐的推出了舞台呢?
Java技术栈
2021/08/12
8250
为什么不推荐使用 stop、suspend 方法中断线程?
Java多线程的基本应用
在JDK1.5推出了TimeUnit类,该类可以根据时间单位来对线程进行睡眠操作;
绿水长流z
2024/06/13
1180
Java多线程的基本应用
多线程基础知识(全面):创建线程、线程状态如何变化、wait()、notify()、sleep()、停止线程
一直想着抽时间 学习多线程相关知识,目前整理了多线程的基础部分,特在此记录下,并发安全、线程池等后续再补充。
寻求出路的程序媛
2024/05/01
2510
多线程基础知识(全面):创建线程、线程状态如何变化、wait()、notify()、sleep()、停止线程
JAVA并行-1.Java线程操作
也可以用Runnable接口新建线程,它只有一个run()方法,而且默认的Thread.run()就是调用内部的Runnable接口,因此使用Runnable更合理。
悠扬前奏
2019/05/28
4740
【并发编程】线程的基础概念
进程是指运行中的程序。 比如我们使用钉钉,浏览器,需要启动这个程序,操作系统会给这个程序分配一定的资源(占用内存资源)。
程序员波特
2024/03/31
1180
【并发编程】线程的基础概念
Java 多线程学习
这些动作都可以抽象为任务,虽然看起来一心二用,但人只有一个大脑,在一个时间片刻只能处理一个任务。
默 语
2024/11/20
1030
Java 多线程学习
线程基础知识归纳
初始(NEW):新创建了一个线程对象,但还没有调用start()方法。 运行(RUNNABLE):处于可运行状态的线程正在JVM中执行,但它可能正在等待来自操作系统的其他资源,例 如处理器。 阻塞(BLOCKED):线程阻塞于synchronized锁,等待获取synchronized锁的状态。 等待(WAITING):Object.wait()、join()、 LockSupport.park(),进入该状态的线程需要等待其他线程做出一些特 定动作(通知或中断)。 超时等待(TIME_WAITING):Object.wait(long)、Thread.join()、LockSupport.parkNanos()、 LockSupport.parkUntil,该状态不同于WAITING,它可以在指定的时间内自行返回。 终止(TERMINATED):表示该线程已经执行完毕。
Dream城堡
2019/05/17
4220
java高并发系列 - 第6天:线程的基本操作
新建线程很简单。只需要使用new关键字创建一个线程对象,然后调用它的start()启动线程即可。
路人甲Java
2019/12/10
4730
java高并发系列 - 第6天:线程的基本操作
Java基础16:Java多线程基础最全总结
本文介绍了Java多线程的基本概念,使用方法,以及底层实现原理。帮助你更好地使用Java的多线程。
程序员黄小斜
2019/04/07
8280
Java多线程编程(一)
1.2.进程的特征: 进程是操作系统进行资源分配和调度的基本单位。  2.线程:  一个线程就是一个 "执行流". 每个线程之间都可以按照顺序执行自己的代码. 多个线程之间 "同时" 执行着多份代码.  例子: ⼀家公司要去银行办理业务,既要进行财务转账,⼜要进行福利发放,还得进⾏缴社保。 如果只有张三⼀个会计就会忙不过来,耗费的时间特别长。为了让业务更快的办理好,张三⼜找来两 位同事李四、王五⼀起来帮助他,三个⼈分别负责⼀个事情,分别申请⼀个号码进⾏排队,⾃此就有 了三个执行流共同完成任务,但本质上他们都是为了办理⼀家公司的业务。 此时,我们就把这种情况称为多线程,将⼀个⼤任务分解成不同⼩任务,交给不同执⾏流就分别排队 执⾏。其中李四、王五都是张三叫来的,所以张三⼀般被称为主线程。
用户11305962
2024/11/21
800
Java多线程编程(一)
1.7停止线程
线程停止:在线程处理完任务之前,停掉正在做的操作,也就是放弃当前操作。 在java中有三种方法可以实现线程的停止: 使用退出标志,使线程正常退出,也就是当run方法执行完后线程终止。 使用stop强行
用户1134788
2017/12/27
1.9K0
1.7停止线程
Thread 类
Runnable 接口内唯一声明了 run 方法,由 Thread 类实现。开发者在 run 方法中定义运行时线程将要执行的功能,线程开启后由 JVM 自动调用并执行。如果开发者主动调用 run 方法,只会当作普通方法执行。
Qwe7
2022/08/06
3420
深入理解线程通信
两个线程通过对同一对象调用等待 wait() 和通知 notify() 方法来进行通讯。
爱明依
2022/04/01
2510
深入理解线程通信
两个线程通过对同一对象调用等待 wait() 和通知 notify() 方法来进行通讯。
crossoverJie
2022/08/19
2480
深入理解线程通信
Java 多线程基础
多线程(multithreading):指从软件或者硬件上实现多个线程并发执行的技术。
星姮十织
2022/01/02
3720
进程与线程
除此之外,我们在JDK8之后,我们可以采用函数式接口Lambda来简化Runnable的书写:
秋落雨微凉
2022/11/18
7490
进程与线程
多线程基础
<font color="red">中央处理器</font>: 作为计算机系统的运算和控制的核心,是信息处理、程序运行的最终执行单元。
程序员NEO
2023/09/30
2440
多线程基础
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
阿华代码,不是逆风,就是我疯,你们的点赞收藏是我前进最大的动力!!7000字长文,希望本文内容能够帮助到你!
三三是该溜子
2024/12/30
870
【JavaEE】线程创建和终止,Thread类方法,变量捕获(7000字长文)
Java并发编程之基础
使用FutureTask可以用泛型指定线程的返回值类型(Runnable的run方法没有返回值)
冬天vs不冷
2025/01/21
730
Java并发编程之基础
相关推荐
线程,JVM锁整理
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档