zoukankan      html  css  js  c++  java
  • 第七天学习多线程的各种方法

    多线程的各种方法

    线程状态

    • 新生状态:创建(new)一个线程。
    • 就绪状态:调用start()时,线程就等待cpu调度。
    • 运行状态:cpu开始调度,进入运行状态,线程执行线程体代码块。
    • 阻塞状态:当调用sleep、wait、同步锁时,线程进入阻塞状态,代码不会继续执行,等待阻塞结束后,重新进入就绪状态,等待cpu调度。
    • 死亡状态:线程中断或结束即进入死亡状态,线程再不能。

    线程方法

    setPriority(int newPriority)      //更改线程优先级
    static void sleep(long millis)    //指定毫秒内让当前线程休眠
    void join()                       //等待线程终止
    static void yield()               //暂停当前线程,执行其它线程
    void interrupt()                  //中断线程
    boolean isAlive()                 //测试线程是否处于活动状态    
    

    停止线程

    • 建议线程正常停止(利用次数,不建议死循环)

    • 建议使用标志位

    • 不要使用stop或destroy等过时或JDK不建议使用的方法。

    package thread;
    public class ThreadTest implements Runnable {
        //1.设置一个标志位
        private boolean flag = true;
    
        //线程体
        @Override
        public void run() {
            int i = 0;
            while (flag){//当flag==false时线程停止
                System.out.println("线程在运行"+i++);
            }
        }
    
        //2.设置一个公开方法,转换标志位
        public void stop(){
            this.flag = false;
        }
        
        public static void main(String[] args) {
            ThreadTest threadTest = new ThreadTest();
            new Thread(threadTest).start();
    
            for (int i = 0; i < 1000; i++) {
                System.out.println("main"+i);
                if (i==900){
                    threadTest.stop();
                    System.out.println("线程停止了");
                }
            }
        }
    }
    

    休眠线程_sleep

    • sleep指定当前线程阻塞毫秒数。
    • sleep存在异常interruptedException。
    • sleep时间到达后,线程进入就绪状态。
    • sleep可以模拟网络延时,倒计时
    • 每一个对象都有一个锁,sleep不会释放锁。

    线程休眠作用

    1. 模拟网络延时,放大问题发生性(代码见多线程创建博客)。
    2. 模拟倒计时
    package thread;
    //倒计时
    public class TestSleep {
    
        public static void tenDown() throws InterruptedException {
            int num=10;
            while (true){
                Thread.sleep(1000);
                System.out.println(num--);
                if (num<=0){
                    break;
                }
            }
        }
        public static void main(String[] args) throws InterruptedException {
            tenDown();
        }
    }
    

    线程礼让_yield

    • 礼让线程,让当前正在执行的线程暂停,但不阻塞。
    • 将线程从运行状态转换为就绪状态。
    • 让cpu重新调度,礼让不一定成功,看cpu心情(线程A在运行,B在就绪,A执行了yield方法,A、B同时就绪,但第二次cpu又调度了A)。

    线程强制执行_join

    • join合并线程,此线程执行后,其它线程才执行。
    package thread;
    
    //测试join
    public class TestJoin implements Runnable {
        @Override
        public void run() {
            for (int i = 0; i < 100; i++) {
                System.out.println("VIP来了"+i);
            }
        }
        public static void main(String[] args) throws InterruptedException {
            TestJoin testJoin = new TestJoin();
            Thread thread = new Thread(testJoin);
            thread.start();
            //主线程
            for (int i = 0; i < 1000; i++) {
                if (i==50){
                    thread.join();
                }
                System.out.println("main"+i);
            }
        }
    }
    
    • 一开始run线程和main主线程一起跑,当主线程 i==50 时,开始全部跑run线程。

    观察线程状态

    package thread;
    
    //观察测试线程状态
    public class TestState {
       public static void main(String[] args) throws InterruptedException {
           Thread thread = new Thread(()->{
               for (int i = 0; i < 5; i++) {
                   try {
                       Thread.sleep(1000);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
               }
               System.out.println("////////");
           });
           //观察创建后
           Thread.State state = thread.getState();
           System.out.println("观察线程启动时的状态---------------》"+state);
           //观察启动后
           thread.start();
            state = thread.getState();
           System.out.println("观察线程运行时的状态---------------》"+state);//run
           //TERMINATED线程终止
           while (state!=Thread.State.TERMINATED){
               Thread.sleep(100);
               state = thread.getState();//更新线程状态
               System.out.println("观察线程休眠时(阻塞)和结束的状态---------------》"+state);
           }
           thread.start();//这里会爆出异常,线程死亡后就在其不能了!
       }
    }
    
    • 使用thread.getState()方法即可观察到线程状态。

    线程的优先级

    • 线程优先级越高,越容易被cpu调度。默认为5,可设置1-10。
    package thread;
    //测试线程优先级
    public class TestPriorty extends Thread{
    
        public static void main(String[] args) {
            //主线程默认优先级
            System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority());
    
            MyPriority testPriorty = new MyPriority();
            Thread thread1 = new Thread(testPriorty,"1");
            Thread thread2 = new Thread(testPriorty,"2");
            Thread thread3 = new Thread(testPriorty,"3");
            Thread thread4 = new Thread(testPriorty,"4");
            
            //默认优先级为5
            thread1.start();
    
            thread2.setPriority(1);
            thread2.start();
    
            thread3.setPriority(4);
            thread3.start();
    
            thread4.setPriority(10);
            thread4.start();
        }
    }
    
    class MyPriority implements Runnable{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority());
        }
    }
    

    守护线程_daemon

    • 线程分为用户线程和守护线程。
    • 虚拟机必须确保用户线程执行完毕(main())。
    • 虚拟机不用等待守护线程执行完毕(gc())。
    package thread;
    
    //测试守护线程
    //上帝守护你
    public class TestDaemon {
    
        public static void main(String[] args) {
            God god = new God();
            You you = new You();
    
            Thread thread = new Thread(god);
            thread.setDaemon(true);//默认是false表示用户线程,正常的线程都是用户线程
    
            //上帝 守护线程启动
            thread.start();
            //你 用户线程启动
            new Thread(you).start();
        }
    
    }
    
    //上帝
    class God implements Runnable{
    
        @Override
        public void run() {
            while (true){
                System.out.println("上帝保佑你一生");
            }
        }
    }
    
    //你
    class You implements Runnable{
        
        @Override
        public void run() {
            for (int i = 0; i < 365000; i++) {
                System.out.println("开心的活了一生");
            }
            System.out.println("=============================Goodbye world");
        }
    }
    
    • 当用户线程执行结束后,守护线程还在执行。
  • 相关阅读:
    图的深度优先遍历(邻接表,递归,非递归)
    图的深度优先遍历(邻接矩阵,递归,非递归)
    【转】C语言邻接表的实现
    图的存储
    堆排序_C实现
    快排_C实现
    交换二叉树中所有结点的左右子树的位置
    二叉树层次遍历_判断结点所属层次
    二叉树_非递归先中后序_递归非递归求深度
    二叉树非递归遍历(前、中、后)
  • 原文地址:https://www.cnblogs.com/sxblogs/p/12894570.html
Copyright © 2011-2022 走看看