多线程基础知识

1、进程:在操作系统中运行的程序就是进程。(例如:看视频)

    一个进程可以有多个线程。(例如:视频中的画面、声音、看字幕)

2、线程:线程是进程中的一个执行单元,负责当前进程中程序的执行。

核心概念:

  1)线程就是独立的执行路径;多线程指多条路径;

  2)在程序运行时,即使自己没有创建线程,后台也会存在多个线程,如gc线程、主线程;

  3)main()称之为主线程,为系统的入口点,用于执行整个程序;

  4)在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序不能人为干预;

  5)对同一份资源操作时,会存在资源抢夺问题,需要加入并发控制;

  6)线程会带来额外的开销,如CPU调度时间、并发控制开销;

  7)每个线程在自己的工作内存交互,加载和存储内存控制不当会造成数据不一致。

 

3、创建线程

  1)继承Thread类

    将类声明为Thread的子类,这个子类要重写run方法,然后可以分配并启动子类的实例。

    class MoreThread extends Thread{

      string name;

      MoreThread(string name){

        this.name = name;

      }

      public void run(){

        //线程体

      }

    }

    //以下代码将创建一个线程并启动它:

    MoreThread mt = new MoreThread("张豆豆");        //创建子类对象

    mt.start();                                                                //启动,开启新的线程,不一定立即执行,系统安排调度分配执行                

  2)实现Runnable接口

    声明一个实现Runnable接口的类。这个类实现了run方法,然后分配类的实例,在创建Thread时作为参数传递,并启动。

    class MoreThread implements Runnable{

      string name;

      MoreThread(string name){

        this.name = name;

      }

      public void run(){

        //线程体

      }

    }

   //以下代码将创建一个线程并启动它:

         (1) //创建实现类对象

     MoreThread mt = new MoreThread("张豆豆");

            //创建代理类对象

            Thread t = new Thread(mt);

            //启动

            t.start();

 

        (2)//创建代理类对象,并启动

     new Thread(mt).start();

 

          (3) //匿名

               new Thread(new MoreThread()).start();

 

  3)实现Callable接口 (JUC并发编程)

                     class CDownloader implements Callable{

                            private String url;

                            private String fname;

                            public CDownloader(String url,String fname) {

                                   this.url = url;

                                   this.fname = fname;

                            }                  

                            @Override

                            public Object call() throws Exception {

                                   WebDownloader downloader = new WebDownloader();

                                   downloader.download(url, fname);

                                   return true;

                            }            

                     }

 

                     使用:

                     (1) 创建目标对象:CDownloader cd = new CDownloader("图片地址","pica.png");

                     (2) 创建执行服务:ExecutorService ser = Executors.newFixedThreadPool(1);

                     (3) 提交执行:Future<Boolean> result1 = ser.submit(cd);

                     (4) 获取结果:boolean b = result1.get();

                     (5) 关闭服务:ser.shutdownNow();

 

4、静态代理:Runnable接口实现多线程中启动必须借助Thread类对象,Thread类对象就是静态代理。

                     /**

                      *   设计模式:静态代理

                      * 1、真实角色

                      * 2、代理角色

                      * 两个角色实现同一个接口            

                      *

                      */

                     public class StaticProxy {

                            public static void main(String[] args) {

                                   new WeddingCompany(new You()).happyMarry();

                                   //new Thread(线程对象).start();

                            }

                     }

 

                     interface Marry{

                            void happyMarry();

                     }

 

                     //真实角色

                     class You implements Marry{     

                            @Override

                            public void happyMarry() {

                                   System.out.println("我们结婚了!");                              

                            }

                     }

                     //代理角色

                     class WeddingCompany implements Marry{                         

                            //真实角色

                            private Marry target;

                            public WeddingCompany(Marry target) {

                                   this.target = target;

                            }

                            @Override

                            public void happyMarry() {

                                   ready();

                                   this.target.happyMarry();

                                   after();           

                            }

                           

                            private void ready() {

                                   System.out.println("布置婚房");

                            }

                           

                            private void after() {

                                   System.out.println("闹洞房");

                            }

                     }

 

5、lamda 表达式:避免匿名内部类定义过多、简化线程的使用(用一次)         

              其实质属于函数式编程的概念

              new Thread(()->System.out.println("Lamda")).start();

              推导过程:

                     外部类-->静态内部类-->局部内部类-->匿名内部类-->lambda

                     lambda推导必须存在类型

6、 线程状态

  

  (1)   进入就绪状态的原因

    a、start()        b、解除阻塞        c、yield()(运行状态到就绪状态)   d、JVM将CPU从本地切换到其他线程

  (2) 导致阻塞状态的原因

    a、sleep()       b、wait()        c、join()         d、read/write

7、线程方法:

  (1)线程停止:

         不使用jdk提供的stop()/destroy()方法;

         提供一个boolean型的终止变量,当变量为false时停止线程的运行。

  (2)sleep()方法          <静态方法>

         如果调用了sleep方法后,没有其他等待执行的线程,当前线程不会马上恢复运行。

         指定当前线程阻塞的毫秒数;

         存在异常InterruptedException;

         时间到了后线程进入就绪状态;

         可以模拟网络延时、倒计时;

         每一个对象都有一个锁,sleep不会释放锁。

  (3)join()方法            <对象方法>

         合并线程、插队线程

         阻塞指定线程等到另一个线程完成以后再继续执行。

  (4)yield()方法           <静态方法>

         让当前正在执行的线程暂停,不是阻塞线程,而是转入就绪线程;

    调用yield后,如果没有其他等待的线程,当前线程就会马上恢复执行。

  (5) setDaemon()

         可以将指定的线程设置成后台线程,守护线程;

         创建用户线程的线程结束时,后台线程也随之消亡;

         只能在线程启动前把它设为后台线程。

  (6) Priority线程的优先级

    setPriority(int newPriority) /getPriority()

         线程的优先级代表的是概率,范围从1到10,默认为5。

         优先级的设定建议在start()调用前

  (7) isAlive() :判断线程是否还活着,线程是否还为终止

  (8)setName() 给线程起名、getName 获取线程名字

  (9) currentThread() 取得当前正在运行的线程对象

 

8、线程分类

  用户线程:java虚拟机必须等这个线程执行完才会停止

  守护线程:java虚拟机不需要等这个线程是否执行完毕

        守护线程为用户线程服务

posted @ 2021-03-06 14:55  禾野牧村  阅读(97)  评论(0)    收藏  举报