线程的理解

1.线程是一个程序里面不同的执行路径.也就是一个程序往多条道路多个方向同时执行(执行路径).

2.进程是一个静态的概念,进程指的是程序本身.当把程序代码加载进内存的时候,只是说明进程已经准备开始了,也就是说进程已经产生了,但是没有开始,所以说进程是一个静态的概念.
    平时所说的进程的执行指的是进程里面的主线程已经开始执行了,也就是main方法开始执行了.然后再main方法里面分支其他的线程.其实进程多个线程的集合,多个线程的运行结果综合在一起就形成了一个进程,也就是我们说的程序.
     在机器里面,其实执行的都是线程.

3.按道理说电脑是计算机,哪怕你运算速度再快,终究在某个时间点你只能干一件事情,难道cpu真的那么神通广大,在同一时间可以干多件事情?
    原因:其实是因为cup运行速度很快很快,一秒钟能执行好几亿次.所以cpu把自己的时间分成一段一段的时间片,cup一会执行这个线程,一会执行那个线程,速度相当之快,看起来好像是两个线程同时运行似的,其实在某个时刻只有一个线程在运行.
    一秒钟对于cpu来讲已经很长很长了,可以把cpu的一秒比喻成我们的一年,cpu第一个月执行线程A,第二个月执行线程B,第三个月执行线程N...
    在我们眼里看到的1秒钟,各个线程好像同时运行..其实这并不是真正意义上的线程并发,真正意义上的线程并发是同一时刻,两个线程同时运行,比如说双核 cpu

4.java的线程是通过java.lang.Thread类来实现的,通过调start()方法来启动一个线程

5.创建新线程的两种方式
    1).定义线程类实现Runnable接口
    2).定义一个Thread的子类,并重写run方法
    通常是实现Runnable接口来创建新线程的,毕竟类只能单一继承,通过实现接口的方法增加了该线程的灵活性.
    原则:尽量使用实现Runnable接口的方式来创建新的线程

6.注意:重写的方法不能跑出和原方法不同的异常;

7.线程的状态
    线程有就绪状态,运行状态,阻塞状态和终止状态
    当我们用new关键字创建一个线程在你调用start()的时候,因为cpu可能正在处理别的线程,或者前面还有别的线程在排队,所以该线程会进入就绪状态.当cpu处理完一个线程,正好轮到你的线程的时候,你的线程就进入运行状态.在执行的过程中,如果有意外情况发生了,你必须等这个情况解决过后才能运行,这个叫做阻塞状态.当情况解决后,还可以继续进入就绪状态.当线程的所有内容都执行完了,线程就终止了.

8.线程控制的基本方法
    isAlive()         判断线程是否还"活"着,的即线程是否还未终止.(线程没有启动或是终止状态就是死的)
    getPriority()     获得线程的优先级的数值
    setPriority()    设置线程的优先级数值
    Thread.sleep()    将当前线程睡眠并指定毫秒数(被打断会跑出异常)
    join()        调用某线程的该方法,将当前线程与该线程"合并",即等待该线程结束,再回复当前线程的运
            行,相当于方法调用了
    yield()        让出cpu,当前线程进入就绪队列等待调度
    this.wait();        //表示让锁定当前对象的线程等待...wait()是Object的方法 (如果线程A锁定了当前对象,那么this.wait()就会让线程A等待)
    this.notify();    //指的是叫醒在当前对象等待的线程,notifyAll()则叫醒全部等待在当前对象上的线程

9.注意:
   1.在哪个线程里面调用了sleep()方法,就让哪个线程睡眠;
     比如:在main方法里面编写了Thread.sleep(10000)方法,就表示让main线程休眠10秒
   
    2.当线程在睡眠的时候,可以用interrupt打断睡眠状态,并会抛出异常.
    
    3.同一个线程类可以实例化多个线程,也就是可以启动多个线程.

    4.System.out.println("当前正在执行的线程是:"+Thread.currentThread().getName());  //拿到当前正在执行的线程

10.yield()方法的使用
    比如cpu给A线程执行10秒,当执行到3秒的时候,A线程调用yield()方法,把剩余的7秒让给B线程执行,然后进入就绪状态,再等到自己执行的时候再执行.只有调用一次yield()的时候才让出cpu一次,并不是永久的让.

11.线程的优先级
    Java提供了一个线程调度器来监控程序中启动后进入就绪状态的所有线程.该调度器按照线程的优先级来决定调度哪个线程来执行.范围是1~10级,标准级是5;
    理解:
             NORM_PRIORITY是标准级
            设置线程的优先级t1.setPriority(Thread.NORM_PRIORITY+3) 
             所谓的优先级就是cpu给优先级高的线程每次多分一些时间片,所以优先级高的线程
                        更有机会先完成,这就是所谓的优先.并不是要等优先级高的彻底执行完成后才给优先级低的执行.

12.让线程停止的方法
    线程停止的原理:run()方法停止,线程就停止;
    interrupt()方法比较粗暴;
    stop()方法更粗暴;
    我们可以在线程类里面写个shutDown()方法,让while(flag)的标志位置为false就让线程停止了;

13.synchronized void add(String name)表示:在执行add方法的过程中,当前对象也被锁定.
     这个当前对象应该是指add方法所在的对象.
     //synchronized (this){        //也可以这么锁定,this表示当前对象,在方法前面写,隐式的锁定当前对象
     什么叫锁定当前对象?
    就是说,当前对象被锁定的时候,无法被其它线程锁定.
     使用synchronized产生两种效果:1.保证锁定代码段的原子性 2.锁定当前对象,取保其它用synchronized修饰的代码段,不能在当前对象被锁定期间执行;

14.当别人问synchronized是什么的时候,该怎么回答?
      synchronized是一个关键字,表示可以给指定的方法加锁.在执行该方法的过程中,该方法被锁定,在同一时间段内,只能有一个线程访问此方法.
      比如A线程正在访问一个方法,B线程也要访问这个访问,若果该方法已被synchronized锁定,则B线程必须等A线程执行完
      了该方法才能访问该方法.
      然而,其他线程却可以访问其它没有被锁定的方法;

synchronized 关键字,代表这个方法加锁,

15.什么是线程同步?
    错误的理解:
        总以为是多个线程同时执行,那就大错特错了.
    正确的理解:
        同步就是协同步调,按预定的先后次序进行运行。如:你说完,我再说。
        “同”字从字面上容易理解为一起动作,从而造成错误的理解;其实不是,
        "同”字应是指协同、协助、互相配合。
        如进程、线程同步,可理解为进程或线程A和B一块配合,A执行到一定
        程度时要依靠B的某个结果,于是停下来,示意B运行;B依言执行,再将结果给A;A再继续操作
        所谓同步,就是在发出一个功能调用时,在没有得到结果之前,该调用就不返回(执行完才能返回),
        同时其它线程也不能调用这个方法。按照这个定义,其实绝大多数函数都是同步调用(例如sin, isdigit等)。
        但是一般而言,我们在说同步、异步的时候,特指那些需要其他部件协作或者需要一定时间完成的任务。
        例如Window API函数SendMessage。该函数发送一个消息给某个窗口,在对方处理完消息之前;
        这个函数不返回。当对方处理完毕以后,该函数才把消息处理函数所返回的LRESULT值返回给调用者。
         在多线程编程里面,一些敏感数据不允许被多个线程同时访问,此时就使用同步访问技术,保证数据
        在任何时刻,最多有一个线程访问,以保证数据的完整性。
    一句话概括:
        多个线程之间协同步调,按预定的先后次序进行运行.防止线程在不能被打断的地方被打断,造成错误.

16.线,程死锁的问题,参考工程的Demo08,可以用到面试中去.

17.注意:
    当我们锁定对象中的某个方法的时候,虽然说同时也锁定当前对象,这也是只是针对于这个被锁定的方法,
     其它未被锁定的方法或者其它部分仍然可以访问;
    锁定当前对象的正确理解:
        如果某个被锁定的方法fun1()正在执行,那么当前对象也被锁定,这个当前对象被锁定是指该对象中
        所有被加了synchronized方法或者代码段都得等fun1()执行完了才可以执行.当然,如果没有被synchronized
        修饰的方法或者代码段,依然可以以被访问;
        可以把synchronized比作一把锁,A,B,C三个方法都被synchronized修饰,哪个方法先抢到这把锁,谁就先执行.
               深刻理解:synchronized(A),就要是我要给A加上锁,如果A是公共的话,其他人想synchronized(A)的话,就得等待...
                             一般this.class对所有实例都是是公共的,所以如果我们给this.class加上synchronized话,所有的实例当要synchronized(this.class)
                 都得等待.若是synchronized(this)的话,只有在当前对象(比如说当前对象的其他方法要synchronized(this)的时候要等待)..
                 由上可以,括号里面若是x,则当x一样一样的时候,就要等待,若是不一样,就不需要等待.

18.结合上面的理解:
        多线程并发的过程中,多加几个synchronized可能会造成效率问题,毕竟有等待时间.
        但是少加的话,可能会造成数据错误问题.
        从而加synchronized的时候一定要小心;

19.wait()和sleep()的区别:
    1).wait()是Object的方法,让锁定当前对象的线程等待(也就是睡眠),在别的线程里面用notify()叫醒;睡眠时失去对当前对象的锁定;
    2).sleep()是Thread的方法,睡眠的时候依然锁定当前对象,时间到了就醒来.

20.线程概念
    线程是一组指令的集合,或者是程序的特殊段,它可以在程序里独立执行。
    简单来说,就是一组独立运行的指令集合,或者说是一段独立运行的代码流程;
    面试回答:
        独立运行的程序片断叫作“线程”(Thread);比如说独立于main方法运行的程序片段;

21.进程的概念
    进程就是程序的一个实例,它拥有一个主线程main方法,在主线程内可以分支其他的线程,
    主线程的执行和其他线程的同步运行就是进程的执行,也就是程序的执行;
    多线程的执行综合效果就是程序执行的效果.

22.线程的各种细节在工程里面,特别是最后一个经典案例,生产者和消费者之间的关系;

猜你喜欢

转载自blog.csdn.net/pengyu1801/article/details/83956632
今日推荐