前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >话说 线程创建&启动&停止

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

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

线程创建&启动&停止

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

1. 创建
代码语言:txt
复制
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
复制
// 启动线程
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
输出:
这是一个线程01!
这是一个线程02!
这是一个线程03!
这是一个线程04!
这是一个线程05!

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

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

执行完for循环 自动结束

代码语言:txt
复制
// 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
复制
 // 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
复制
// 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
复制
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
复制
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
复制
// 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
复制
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 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 线程创建&启动&停止
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档