多线程简介(3)

来源:互联网 发布:cms stop the world 编辑:程序博客网 时间:2024/06/16 08:53

多线程的基本概念

1)多任务处理有两种类型:基于进程和基于线程


2)多进程:进程是运行中的程序,有其自己的地址和空间, 即“ 自包容”的;基于进程的计算机能同时运行多个程序,即多进程 。

      1、线程是进程内部一个单一的顺序的控制流

      2、线程是进程内的一段的执行中的代码( 控制流 ), 该代码段的是按顺序执行的 ( 串行 ),不存在任何两条代码同时执行的情况


3)多线程:一个进程中可同时存在多个线程, 即多线程 。

      1、基于线程的多任务( 多线程 ) 环境中 , 线程是最小的处理单位,即线程中不再有并行的控制流。

      2、一个线程执行一个任务,多个线程并发执行多个任务

      3、线程内部不会并行多个任务


4)基于线程多任务处理的优点:

      1、基于线程所需的开销更少。

      2、在基于进程多任务环境中, 各个进程需要分配他们自己独立的地址空间。

      3、多个线程可共享相同的地址空间并且共同分享同一个进程。

      4、进程间调用涉及的开销比线程间通信多。

      5、 线程间的切换成本比进程间的切换成本低。

Java 中的多线程

1)Java 中的多线程 :

      1、线程是对象,是Thread类的对象。

      2、 一个应用程序可以包含多个线程。每个线程执行特定的任务,并可与其他线程并发执行。


2)主线程 :

      1、Java 程序本身就是基于线程的,一个 Java 程序至少包含一个线程,即主线程。当启动 Java程序时,主线程立刻运行。

      2、 main 方法所在的线程即为主线程 。

      3、主线程的重要性主要体现在 : 它是产生其他线程的线程。


3)创建线程的方法 :

1、 声明一个Thread类的子类,并覆盖run()方法。

class MyThread extends Thread{Public void run(){// 覆盖该方法} }

2、声明一个实现Runnable 接口的类,并实现run()方法。

class  MyThread implements  Runnable{ {Public void run(){// 实现该方法} }


4)线程的启动 :

      1、要启动一个新线程,使用 start() 方法。例如: MyThread t=new  MyThread ();t.start ();

      2、在调用 start()方法时,该线程启动,并被放入线程调度队列中;Java虚拟机负责调度该线程,并调用该线程的 run()方法。

      3、run() 方法具体实现线程功能。

      注意:不能通过直接调用 run 方法 () 来启动线程。


线程启动示例

线程的状态

1)线程的状态 :

      1、新建(NEW):线程对象被创建,其start()尚未被调用,此时线程即为新建状态。

      2、就绪/ /可运行(RUNNABLE):线程对象的start()方法已被调用,正在等待CPU 的使用权,此时即为就绪状态。

      3、运行(RUNNING ):线程占用 CPU , 执行程序代码 , 此时线程即为运行状态 。

      4、阻塞(BLOCKED/WAITING/ / TIMED_WAITING ):线程对象放弃CPU,暂时停止运行,不会再竞争占用 CPU ,此时线程即处于阻塞状态。 例如在线程等待一个事件时 ( 例如 I/O 输出操作、结束睡眠、唤醒或者其它某个线程结束等等)。

      5、死亡(TERMINATED):线程对象的run()方法已完成执行(或其stop()方法被调用之后), 线程就处于死亡状态 。


2)关于阻塞状态(阻塞状态的表现形式)

      1、睡眠(SLEEPING):线程的执行通过使用sleep() 方法暂时中止。

      2、等待(WAITING/ /TIMED_WAITING):如果调用了wait()、join()方法,线程将处于等待状态。用于协调两个或多个线程并发运行。

      3、挂起( suspended ):在临时停止或中断线程的执行时,线程就处于挂起状态(直到被恢复- - resume )。(该状态已过期,不建议使用)等待 I/O 操作等等。

      4、注意:处于阻塞状态下的线程对象不会竞争和占用CPU,线程对象结束阻塞状态将进入就绪状态,而不是进入运行状态。


3)Thread 类的部分方法与线程状态的关系 :

      1、 Thread.sleep() 方法使当前线程睡眠。从运行状态进入阻塞状态 , 睡眠结束从阻塞状态进入就绪状态 。

      2、调用其它线程的join()方法,使当前线程等待其它线程运行完毕。当前线程进入阻塞状态,结束等待后从阻塞状态进入就绪状态。

      3、线程由于等待一个I/O事件被阻塞。从运行态进入阻塞态,结束阻塞后从阻塞状态进入就绪状态。

      4、对象的wait()方法,使当前线程等待。(需和同步机制配合使用)从运行状态进入阻塞状态,结束等待后从阻塞状态进入就绪状态。

      5、Thread.yield()方法,使当前线程显式出让CPU控制权(让步)。从运行状态进入就绪状态。

      注:在实际应用中,上述方法是实现线程调度策略重要手段。

线程的优先级

1)Java中的线程优先级是在Thread类中定义的常量:

     1、NORM_PRIORITY:值为5

      2、MAX_PRIORITY:值为10

      3、MIN_PRIORITY:值为1

      4、默认优先级为 : :  NORM_PRIORITY 


2)有关优先级的方法有两个 :

      1、final voidsetPriority(int newPriority):更改线程的优先级。

      2、final intgetPriority():返回线程的优先级。


3)优先级的作用

      1、优先级决定了线程占用CPU的概率,较高优先级的线程占用 CPU 的可能性较大。

      2、合理设置优先级是实现线程调度策略的手段之一。

     注意:当某一时刻有多个就绪线程时,优先级并不能确定某个线程能否占用CPU。优先级确定的仅是宏观上的概率和可能性。

线程调度

1)线程调度概念

      合理分配多个线程对CPU资源占用,即线程调度。


2)线程调度的原因

      多线程对 CPU 大量需求与 CPU 的数量不足之间的矛盾。


3)线程调度是从宏观角度出发的

      1、线程调度仅仅是从整体上确保多线程对 CPU 的占用分配符合程序设计的需要。

      2、在微观上,线程具体何时、何步骤占用CPU和放弃CPU 一般是无法预知的。


4)线程调度的策略

      1、任何线程都有占用CPU的机会

      2、防止线程长期占用CPU不放弃,即应该控制线程适当放弃对 CPU 的占用。

      3、符合其它策略目标


5)线程调度的实现手段

      1、合理设定优先级

      2、使用Thread.yield()、Thread.sleep()、join()等方法等等。

原创粉丝点击