Java的线程种类

作者: Android开发哥 | 来源:发表于2017-02-26 14:21 被阅读565次

    线程的声明周期图

    原理图1

    守护线程

    什么是守护线程

    java线程一共分成两种,用户线程守护线程.

    默认就是用户线程,那么什么是守护线程?
    当A线程去启动B线程的时候,如果当A线程死掉的时候,如果B是守护线程,则B也跟着死掉,反之B继续自己的业务逻辑。

    代码

    普通线程代码

    package snippet;
    class Sub extends Thread {
        
        public Sub(String name) {
            setName(name);
        }
        
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println(getName() + "--->" + i);
            }
        }
    }
    public class test {
        public static void main(String[] args) {
            Sub t1 = new Sub("左护法");
            Sub t2 = new Sub("右护法");
            
            t1.start();
            t2.start();
            
            Thread.currentThread().setName("大哥");
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName() + "--->" + i);
            }
        }
        
    }
    

    这时候的t1和t2默认是用户线程
    但是这么一个场景.程序跑起来,有可能是大哥进程先死掉,那么左右护法活着也没意思,也是应该跟着去死的.但是上面并没有.因为左右护法线程没有被设置为守护线程
    使用setDaemon方法来切换用户线程和守护线程.但该方法必须在start方法之前执行

    守护线程代码

    package snippet;
    class Sub extends Thread {
        
        public Sub(String name) {
            setName(name);
        }
        
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println(getName() + "--->" + i);
            }
        }
    }
    public class test {
        public static void main(String[] args) {
            Sub t1 = new Sub("左护法");
            Sub t2 = new Sub("右护法");
            
            t1.setDaemon(true);
            t2.setDaemon(true);
            
            t1.start();
            t2.start();
            
            Thread.currentThread().setName("大哥");
            for (int i = 0; i < 100; i++) {
                System.out.println(Thread.currentThread().getName() + "--->" + i);
            }
        }
        
    }
    

    这时候,若有大哥线程先去死的情况,那么左右护法也会跟着大哥线程一起死.

    停止线程

    什么是停止线程

    在Thread类中有两个方法可以打断正在运行的线程一个是stop(),一个是interrupt()方法
    其中如果线程被Object.wait, Thread.join和Thread.sleep三种方法之一阻塞,那么,它将接收到一个中断异常(InterruptedException),而stop的话是直接停掉线程的.java的官方文档中说明建议使用interrupt方法而不是stop方法(不安全).
    对于interrupt方法来说,被中断后只是try语句内的内容被打断,然后抛出异常.try外面的语句继续执行.而stop则是直接停掉整个线程

    停止线程代码

    package snippet;
    class MyThread extends Thread {
        @Override
        public void run() {
            try {
                Thread.sleep(3000);
            } catch (Exception e) {
                e.printStackTrace();
            }
            System.out.println("结束");
        }
    }
    public class test {
        public static void main(String[] args) throws Exception {
            MyThread t1 = new MyThread();
            t1.start();
            
            Thread.currentThread().sleep(1000);
            
            t1.interrupt();
        }
        
    }
    

    最终结束会被输出,但如果使用stop方法,则最后结束不会被输出

    加入线程

    什么是加入线程

    加入线程不属于java的线程分类,它只是一种我们口头的翻译而已.
    什么是加入线程?如果有线程A,B,C一起执行,当三个线程都为普通线程的时候,CPU的资源是靠死抢的.
    但是当A为加入线程的时候,在A执行完毕之前B,C是不会去执行的.
    就是说加入线程优先执行完毕,然后普通线程才去执行.
    特么这不是单线程么...执行有点类似,但是加入线程具有子线程的特性,也不在主线程中运行

    加入线程代码

     package snippet;
    class MyThread extends Thread {
        public MyThread(String name) {
            setName(name);
        }
        
        @Override
        public void run() {
            try {
                for (int i = 0; i < 5; i++) {
                    System.out.println(getName() + "在吃第" + i + "碗饭");
                    Thread.sleep(100);
                }
                System.out.println(getName() + "吃饱了");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    public class test {
        public static void main(String[] args) throws Exception {
            MyThread t1 = new MyThread("女孩");
            MyThread t2 = new MyThread("男孩");
            t1.start();
            
            t1.join();
            
            t2.start();
            
        }
        
    }
    

    先让女的吃饱了,男的才能去吃...

    礼让线程

    什么是礼让线程

    Thread.yield()方法的官方解释是:暂停线程进而去执行其他线程.其中其他线程也包含自己当前的线程

    礼让线程代码

    package snippet;
    class MyThread extends Thread {
        
        public MyThread(String name) {
            setName(name);
        }
        
        @Override
        public void run() {
            System.out.println(getName());
            yield();
            System.out.println(getName());
        }
    }
    public class test {
        public static void main(String[] args) throws Exception {
            MyThread t1 = new MyThread("aaa");
            MyThread t2 = new MyThread("b");
            t1.start();
            t2.start();
        }
        
    }
    

    暂时不知道这东西有什么用...

    相关文章

      网友评论

        本文标题:Java的线程种类

        本文链接:https://www.haomeiwen.com/subject/ucbowttx.html