• ****多线程


    1.多线程:

    多线程
    
    首先需要理解  进程!
    
    进程:  我们应用程序的执行实例!有自己独立的内存空间和系统资源!
    
     一个进程是由一个或者N个线程组成的!
     
    线程:cpu调度和分配的基本单位!电脑中真正执行的是 线程! 
    
     在同一个时间点,我们的电脑只能运行一个线程!
     
    多线程:
         如果在一个进程中,同时运行多个线程,来完成不同的工作,我们称之为多线程!
         
       CPU上能同时运行多个线程吗?  不能! 
          一个CPU在同一个时间点,只能运行一个线程,但是线程运行的速度太快,我们肉眼无法分辨
          所以我们认为是多线程!  
    
    
    
          
    生活中进入地铁站的例子:
    
      场景1:现在地铁站有1个进站口,同时来了5个人旅客!
                   需要排队进站! 
      场景2:现在地铁站有5个进站口,同时来了5个人旅客!
                   不需要排队进站!     
     
     哪个对我们的体验好点呢?
     哪个地铁的设计比较合理呢?
    
    地铁站 :CPU
    进站口 :线程
    
    
    多线程的好处:
      01.充分的利用了CPU的资源
      02.给用户带来了良好的体验
    
    
    
    
    实现多线程的方式:
    
     01.继承Thread类
     02.实现Runnable接口
    
    Thread类   implements  Runnable接口
    
     Runnable接口中
     01. 只有一个方法run()
     02. 没有返回值
     03. 没有声明异常,其实现类的run()如果出现了 异常不能声明,只能try catch
     
     
     
     
     
    run()和 start()的区别:
    
       run():
             01.就是一个普通的方法,称之为线程体!
             02.CPU分配给当前线程时间片的时候,run()开始执行
    
       start():
             01.启动线程,不是立即执行线程!
             02.底层会默认执行run()
     
          
    线程的生命周期:
    
        01.新生状态
           MyThreadDemo t1 = new MyThreadDemo();
        02.就绪状态
           t1.start();
        03.运行状态
           run();
        04.阻塞状态
          sleep ,yield, wait , join 
        05.死亡状态
           001.正常死亡      run()执行完毕 之后   
           002.异常死亡      run()执行过程中,出现异常退出!
             
    
    线程的调度
         按照我们特定的方式给 多个线程设置CPU的使用权!
         
     01.线程的优先级
        setPriority()    优先级越高就一定先执行! 不是的! 只是一个概率问题
        
        
     02.join() 让新线程加入进来
        t1.join() :必须等待t1线程执行完毕之后,其他的线程才能执行!
     
     03.线程的休眠
      sleep() 线程调用的时候,占用CPU资源不释放!其他线程就无法获取CPU资源了!
         其他线程需要等待!
       
      wait()  是Object类中的方法!  线程调用wait() 的时候,释放占用的CPU资源!
                    01.其他线程继续执行!无需等待!
                    02.使用了wait() 的线程,必须notify唤醒才能继续进入就绪状态!
     
     04.线程的礼让   yield      
                  概率问题,我们t1线程想让t2线程执行,有可能t2不接收这个让渡!还是t1执行!    
                         
     05.线程的终止
       001. interrupt : 设置线程的中断状态,不会终止,线程会继续执行!
    		      如果有线程调用这个方法,那么这个线程的状态就是  中断状态!
    		   我们怎么知道这个线程是不是中断状态呢???
    		   isInterrupted可以判断线程的状态!
       002. interrupted:返回线程上次的中断状态!之后清除线程的中断状态!
       003. isInterrupted:返回线程是否是中断状态!
       004. wait(),sleep()如果执行了,会自动清除线程的中断状态!
    2.代码:
    /**
     * 01.继承Thread类
     */
    public class MyThreadDemo extends Thread {
    
        /**
         * 重写父类的run()
         */
        @Override
        public void run() {
            for (int i = 1; i <= 100; i++) {
                System.out.println(Thread.currentThread().getName() + "执行了====》"
                        + i);
            }
        }
    
        // 多线程的并发执行
        public static void main(String[] args) {
            // 创建两个线程对象
            MyThreadDemo t1 = new MyThreadDemo();
            MyThreadDemo t2 = new MyThreadDemo();
            /**
            t1.run();
            t2.run();   这样调用run()  就是普通的方法,一个方法不执行完毕,另一个方法无法执行!所以顺序执行!
            */
    
            // 真正的启动线程 是调用线程类(继承了Thread类或者实现了Runnable接口)的start()
    
            t1.setName("第1个线程");
            t2.setName("第2个线程");
    
            t1.start();
            t2.start();
    
        }
    
    }
    创建线程2种方式,1
    /**
     * 02.实现Runnable接口
     */
    public class MyRunnableDemo implements Runnable {
    
        @Override
        public void run() {
            for (int i = 1; i <= 100; i++) {
                System.out.println(Thread.currentThread().getName() + "执行了====》"
                        + i);
            }
        }
    
        // 多线程的并发执行
        public static void main(String[] args) {
            // 创建线程类对象
            MyRunnableDemo demo1 = new MyRunnableDemo();
            MyRunnableDemo demo2 = new MyRunnableDemo();
    
            // 创建线程对象
            Thread t1 = new Thread(demo1, "第1个线程");
            Thread t2 = new Thread(demo2, "第2个线程");
    
            // 启动线程
            t1.start();
            t2.start();
    
        }
    }
    创建线程2种方式,2
    public class MyThread {
    
        /**
         * 主线程的入口
         */
        public static void main(String[] args) {
            // 获取当前执行的线程
            Thread t = Thread.currentThread();
            System.out.println("当前线程的名称是====》:" + t.getName());
            // 设置线程名称
            t.setName("主线程Main");
            System.out.println("当前线程的名称是====》:" + t.getName());
        }
    
    }
    测试

    3.线程的优先级

    import cn.bdqn.thread.MyRunnableDemo;
    
    /**
     * 线程的优先级
     * 默认是5 
     * 取值是1-10
     * 优先级越高代表获取cpu资源的概率越高!并不代表一定高!(cpu不一定没给分配时间片)
     */
    public class MyThread implements Runnable {
    
        @Override
        public void run() {
            for (int i = 1; i <= 50; i++) {
                System.out.println(Thread.currentThread().getName() + "执行了====》"
                        + i);
            }
        }
    
        // 多线程的并发执行
        public static void main(String[] args) {
            // 创建线程类对象
            MyRunnableDemo demo1 = new MyRunnableDemo();
            MyRunnableDemo demo2 = new MyRunnableDemo();
    
            // 创建线程对象
            Thread t1 = new Thread(demo1, "第1个线程");
            Thread t2 = new Thread(demo2, "第2个线程");
    
            // 获取两个线程的默认优先级
            System.out.println("第1个线程的默认优先级是===》" + t1.getPriority());
            System.out.println("第2个线程的默认优先级是===》" + t2.getPriority());
    
            // 设置t1的优先级为10
            t1.setPriority(10);
            System.out.println("第1个线程的默认优先级是===》" + t1.getPriority());
            System.out.println("第2个线程的默认优先级是===》" + t2.getPriority());
    
            // 启动线程
            t1.start();
            t2.start();
    
        }
    }
    优先级

    4.线程的调度:

    /**
     * t1.sleep() :必须等待t1线程睡醒之后,其他的线程才能执行!
     */
    public class SleepDemo implements Runnable {
        @Override
        public void run() {
            for (int i = 1; i <= 10; i++) {
                try {
                    Thread.sleep(1000); // 线程休眠1秒
                    System.out.println(Thread.currentThread().getName()
                            + "执行了====》" + i);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    
        // 多线程的并发执行
        public static void main(String[] args) {
            // 创建线程类对象
            SleepDemo demo1 = new SleepDemo();
            SleepDemo demo2 = new SleepDemo();
            // 创建线程对象
            Thread t1 = new Thread(demo1, "sleep1的线程");
            Thread t2 = new Thread(demo2, "sleep2的线程");
            t1.start();
            t2.start();
        }
    }
    休眠状态
    /**
     * t1.yield() :线程的礼让!  有可能对方不接受!
     */
    public class YieldDemo implements Runnable {
        @Override
        public void run() {
            for (int i = 1; i <= 50; i++) {
                System.out.println(Thread.currentThread().getName() + "执行了====》"
                        + i);
            }
        }
    
        // 多线程的并发执行
        public static void main(String[] args) {
            // 创建线程类对象
            YieldDemo demo1 = new YieldDemo();
            Thread t1 = new Thread(demo1, "老幼病残线程");
            // 启动辅助线程t1
            t1.start();
            for (int i = 1; i <= 100; i++) { // 在main主线程中进行输出操作
                System.out.println(Thread.currentThread().getName() + "执行的i值:" + i);
                if (i % 2 == 0) {
                    Thread.currentThread().yield(); // 主线程礼让
                }
            }
        }
    }
    线程的礼让
    import cn.bdqn.thread.MyRunnableDemo;
    
    /**
     * t1.join() :必须等待t1线程执行完毕之后,其他的线程才能执行!
     */
    public class JoinDemo implements Runnable {
        @Override
        public void run() {
            for (int i = 1; i <= 50; i++) {
                System.out.println(Thread.currentThread().getName() + "执行了====》"
                        + i);
            }
        }
    
        // 多线程的并发执行
        public static void main(String[] args) {
            // 创建线程类对象
            MyRunnableDemo demo1 = new MyRunnableDemo();
            // 创建线程对象
            Thread t1 = new Thread(demo1, "join的线程");
            // 启动辅助线程t1
            t1.start();
            for (int i = 1; i <= 10; i++) { // 在main主线程中进行输出操作
                System.out.println(Thread.currentThread().getName() + "执行的i值:" + i);
                if (i == 5) {
                    try {
                        t1.join(); // 阻塞主线程main !执行t1
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
    线程的阻塞,强制执行
    /*
     * 设置线程的中止状态
     *分别实现了interrupt 设置中断状态
     *    interrupted:返回线程上次的中断状态!之后清除线程的中断状态!
     *    isInterrupted:返回线程是否是中断状态!
     */
    public class InterruptDemo implements Runnable {
    
        @Override
        public void run() {
    
            // 判断线程是否是中止状态
            if (Thread.currentThread().isInterrupted()) {
                System.out.println("当前线程状态是  中止状态");
            } else {
                for (int i = 1; i <= 50; i++) {
                    System.out.println(Thread.currentThread().isInterrupted());
                    Thread.currentThread().interrupt(); // 设置终止状态
                    System.out.println(Thread.currentThread().getName()
                            + "执行了====》" + i);
                    if (i == 2) {
                        Thread.currentThread().interrupted();// 清除终止状态
                    }
                }
            }
        }
    
        public static void main(String[] args) {
    
            // 创建线程对象
            InterruptDemo demo = new InterruptDemo();
            Thread t = new Thread(demo);
            t.start();// 启动线程
    
        }
    
    }
    线程的中断状态
     
  • 相关阅读:
    20172327 2018-2019-1 《程序设计与数据结构》实验三:查找与排序
    团队作业第二周
    需求规格说明书
    广度优先遍历
    团队作业第一周
    20172327 2018-2019-1 《程序设计与数据结构》第九周学习总结
    20172327 2018-2019-1 《程序设计与数据结构》实验二:树实验报告
    20172327 2018-2019-1 《程序设计与数据结构》第八周学习总结
    20172327 2018-2019-1 《程序设计与数据结构》第七周学习总结
    20172327 2018-2019-1 《程序设计与数据结构》第六周学习总结
  • 原文地址:https://www.cnblogs.com/wwlw/p/7521679.html
Copyright © 2020-2023  润新知