码迷,mamicode.com
首页 > 编程语言 > 详细

Java 复习 —— 多线程基础

时间:2015-09-04 14:29:35      阅读:202      评论:0      收藏:0      [点我收藏+]

标签:

1、基本概念     

1)进程:运行当中的程序,程序是静止的概念,进程的是动态的概念,进程与进程之间互不运影响

2)线程:指程序中单独顺序的流控制,线程依附于进程中,他是最小的执行单位!一个任务一个线程。

3)多线程:指的是单个程序中可以同时运行多个不同的线程,执行不同的任务。(本身就要把线程理解为为不同的任务而服务的)

4)二者关系:一个进程当中可以有一个或多个线程,但是至少有一个线程。


2、作用与关系   

1)多线程的目的:最大限度利用CPU资源

2)主线程:Java程序默认启动一个线程就是main线程,也就是主线程。另外一定要注意main只是一个线程

不是进程,所以main退出不代表进程退出,想要进程退出必须所有线程都停止。

3)进程之间内部数据和状态是完全独立的,但是多线程则是共用寄存器的数据,所以多线程之间会相互影响,但是线程的切换比进程的切换资源负担较小。

4)多个进程的内部数据和状态是完全独立的,而多线程是共享一块内存空间的一组系统资源,相互之间会影响。

5)线程本身的数据通常只有寄存器数据,以及一个程序执行时使用的堆栈,所以线程的切换比进程的切换负担要小。


3、Java 线程定义  

1)继承Thread类,重写run方法,启动时,new 一个实例调用实例的start方法

2)实现Runnable接口,实现run方法;new一个当前类的实例同时作为一个Thread实例的参数调用start

3)每个线程都会有一个名字,这个名字就线程的标识,但是这个标识不是唯一的,也就是可能有多个线程拥有同一个名字。

4)线程执行的代码写在run方法中,然后通过start方法启动线程,然后系统默认为我们调用run方法,这个start的作用就是为线程的执行准备资源,如果你手动调用run方法,那么这个时候启动的线程不是真正的线程。他其实就就是一个普通的方法,不再是以线程的概念运行。

5)对于start方法只能调用一次,而且线程运行完了之后,也不能重重新调用start,而是必须重新new一个线程实例重新调用start;多次调用start会抛出一个线程状态异常(运行是异常)。

6)对于单核多核只是决定并行线程个数的多少,多线程如果只是在单核里面,其实的他们运行的顺序是不受控制的,让人觉得多个线程同时执行(宏观并行),而实际上因为多线程是对CPU资源的竞争,所以,只要某个线程竞争到资源就能运行,多个线程相互竞争之中导致多个任务交叉执行,所以让人觉得多个线程同时执行!单核处理器同样可以运行多个线程,只是这些线程其实是串行(微观串行)的而非并行的,不过他们的执行顺序的确是不确定的,因为同一个时间单核的只能处理一个线程!但是对于多核则不一样,他是真正意义的微观并行,同一时间确实可以有多个线程执行!


4、Thread 与 Runnable 的关系

1)Thread类实现了Runnable接口,实现了run方法,具体实现就是对他的成员变量Runnable变量进行空判断,如果不为空就调用它的run方法,所以我们写一个继承Thread的类必须重新run方法。

2)Runnable是接口,Thread是类,Java单继承的特性决定了Runnable更容易扩展

3)一个Runnable变量可以被多个Thread实例共享,这个对于线程资源共享意义是重大的


5、线程暂停、停止

0)禁止使用stop方法停止线程,这个方法是一个不安全方法(核心就是抛异常的方式),同时也是一个depcrecated方法

1)旗标法停止线程,通过一个标识量来进行循环跳出,这个标识量可以是在循环外赋值,也可以是在循环内改变这个值(这个时候可以直接break、return);

2)使用interrupt的方式停止线程,这个也是不建议使用的,核心也是抛异常的方式,只是因为interrupt在线程处于阻塞状态被调用时会重置线程的interrupted值,从而导致值的不准确性,所以也是不建议使用!

3)通过sleep和yield方法暂停线程,这个是建议使用的,他们都不会释放对象的锁!

4)通过suspend 和 resume 来暂停唤醒线程 是不建议使用的,由于使用这两个方法可能会造成一些不可预料的事情发生,因此,这两个方法被标识为deprecated(弃用)标记,这表明在以后的jdk版本中这两个方法可能被删除!


6、线程生命周期    

1)创建 :new 一个实例之后

2)可运行(就绪):调用了start,也就是就绪状态

3)运行状态:线程获取到CPU资源,正在处理

4)不可运行(挂起、阻塞) : 被阻塞,比如等待IO,等待对象锁等

5)消亡:线程运行完了,或抛了异常

注意,阻塞状态可分为如下几种情况:

A、 位于对象等待池中的阻塞状态:当线程运行时,如果执行了某个对象的wait()方法,java虚拟机就回把线程放到这个对象的等待池中。

B、 位于对象锁中的阻塞状态:当线程处于运行状态时,试图获得某个对象的同步锁时,如果该对象的同步锁已经被其他的线程占用,JVM就会把这个线程放到这个对象的琐池中。

C、 其它的阻塞状态:当前线程执行了sleep()方法,或者调用了其它线程的join()方法,或者发出了I/O请求时,就会进入这个状态中。

技术分享

JDK源码中线程的状态:

A thread state. A thread can be in one of the following states:

  • NEW
    A thread that has not yet started is in this state.

  • RUNNABLE
    A thread executing in the Java virtual machine is in this state.

  • BLOCKED
    A thread that is blocked waiting for a monitor lock is in this state.

  • WAITING
    A thread that is waiting indefinitely for another thread to perform a particular action is in this state.

  • TIMED_WAITING
    A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state.

  • TERMINATED
    A thread that has exited is in this state.

A thread can be in only one state at a given point in time. These states are virtual machine states which do not reflect any operating system thread states.  


7、线程的优先级   

1)如果有优先级的限定可能导致低优先级的线程永远都没有机会执行,这样是不合理的,所以线程的优先级是不能唯一决定的线程的执行的!操作系统会在程序运行时动态控制线程的优先级,比如这个线程等待的时间越长,那么他的优先级就会变高,这样才能保证所有的线程都有机会执行!所以程序员不应该过于依赖优先级来决定线程的执行!

2)设置优先级是为了在多线程环境中便于系统对线程的调度,优先级高线程将优先执行,但是并不建议使用优先级来控制线程的执行顺序;

3)线程创建时,子继承父的优先级

4)线程初始化之后,通过调用setPriority方法改变优先级

5)线程的优先级是1~10之间正整数


8、线程的调度      

线程调度器选择优先级最高的线程运行。但是如果发生以下情况就会终止线程的运行:

A:线程体中调用了yield方法,让出了对CPU资源的占用权

B:线程体中调用了sleep方法,是线程处于休眠状态,也可能会让出对CPU资源的占用权

C:线程由于I/O操作而受阻塞,等其他阻塞状态都会导致原本占用的CPU资源被释放

D:在支持时间片的系统中,该线程的时间片用完


Java 复习 —— 多线程基础

标签:

原文地址:http://my.oschina.net/heweipo/blog/501080

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!