zoukankan      html  css  js  c++  java
  • java中进程与线程的三种实现方式

    一:进程与线程

      概述:几乎任何的操作系统都支持运行多个任务,通常一个任务就是一个程序,而一个程序就是一个进程。当一个进程运行时,内部可能包括多个顺序执行流,每个顺序执行流就是一个线程。

      进程:进程是指处于运行过程中的程序,并且具有一定的独立功能。进程是系统进行资源分配和调度的一个单位。当程序进入内存运行时,即为进程。

     进程的三个特点

      1)独立性:进程是系统中独立存在的实体,它可以独立拥有资源,每一个进程都有自己独立的地址空间,没有进程本身的运行,用户进程不可以直接访问其他进程的地址空间。

      2)动态性:进程和程序的区别在于进程是动态的,进程中有时间的概念,进程具有自己的生命周期和各种不同的状态。

      3)并发性:多个进程可以在单个处理器上并发执行,互不影响。

     并发性和并行性是不同的概念:并行是指同一时刻,多个命令在多个处理器上同时执行;并发是指在同一时刻,只有一条命令是在处理器上执行的,但多个进程命令被快速轮换执行,使得在宏观上具有多个进程同时执行的效果

     


     

    注:

    线程:线程是进程的组成部分,一个进程可以拥有多个线程,而一个线程必须拥有一个父进程。线程可以拥有自己的堆栈,自己的程序计数器和自己的局部变量,但不能拥有系统资源。它与父进程的其他线程共享该进程的所有资源。

    线程的特点

    线程可以完成一定任务,可以和其它线程共享父进程的共享变量和部分环境,相互协作来完成任务。

    线程是独立运行的,其不知道进程中是否还有其他线程存在。

    线程的执行是抢占式的,也就是说,当前执行的线程随时可能被挂起,以便运行另一个线程。

    一个线程可以创建或撤销另一个线程,一个进程中的多个线程可以并发执行。


     二、线程的创建及使用

      java使用Thread类代表线程,所有的线程对象都必须是Thread或者其子类的实例,每个线程的作用是完成一定任务,实际上是就是执行一段程序流(一段顺序执行的代码)

    方案一:继承Thread类创建线程类

       步骤: ① 定义Thread类的子类 并重写该类的Run方法,该run方法的方法体就代表了该线程需要完成的任务

               ② 创建Thread类的实例,即创建了线程对象

                 ③ 调用线程的start方法来启动线程

    结论:使用继承子Thread类的子类来创建线程类时,多个线程无法共享线程类的实例变量(比如上面的i)


     方案二:实现Runnable接口

     ①定义Runnable接口的实现类,并重写它的Run方法,run方法同样是该线程的执行体!

     ②创建Runnable实现类的实例,并将此实例作为Thread的target创建一个Thread对象,该Thread对象才是真正的线程对象!

     ③调用start方法启动该线程

    结论:采用Ruunable接口的方式创建多个线程可以共享线程类的实例变量,这是因为在这种方式下,程序创建的Runnable对象只是线程的target,而多个线程可以共享一个target,所以多个线程可以共享一个实例变量

    通过Runnable实现多线程其实就是将run包装成线程的执行体,但是目前java无法将任意方法包装成线程执行体

     


    方案三:使用callable和future创建线程

    从Java5开始,Java提供 Callable接口,Callable接口提供了一个call()方法可以作为线程执行体,看起来和Runnable很像,但call()方法更强大——call()方法可以有返回值、call()方法可以抛出异常

      Java5提供了Future接口来代表Callable接口的call()方法的返回值,并为Future接口提供了一个FutureTask实现类,该实现类实现类Future接口,也实现了Runnable接口——可以作为Thread的target。

    实现步骤:

      ①创建Callable接口的实现类,并实现call方法,该call方法会成为线程执行体,且call方法具有返回值,在创建callable接口的实现类!

      ②使用FutrueTask类来包装Callable对象,该FutrueTask封装类Callable的call方法的返回值

      ③使用FutrueTask对象作为Thread的target创建并启动新线程!

      ④使用FutrueTask的get方法获取执行结束后的返回值

    结论:采取Runnable、Callable的优势在于——线程类只是实现了Runnable或Callable接口,还可以继承其它类;在这种方法下,多个线程可以共享一个target对象,因此非常适合多个相同线程处理同一份资源的情况,从而将CPU、代码和数据分开,形参清晰的模型,体现了面对对象的编程思想。劣势在于编程复杂度略高。

  • 相关阅读:
    【Javascript】javascript学习 二十二 JavaScript 对象简介
    【Javascript】javascript学习 二十六 JavaScript Boolean(逻辑)对象
    【Javascript】javascript学习 二十九 JavaScript HTML DOM 对象
    【Javascript】javascript学习 二十八 JavaScript RegExp 对象
    【Javascript】javascript学习 二十一 JavaScript 指导方针
    【Javascript】javascript学习 二十三 JavaScript 字符串(String)对象
    【Javascript】javascript学习 三十 JavaScript 浏览器检测
    【Javascript】javascript学习 二十五 JavaScript Array(数组)对象
    【Javascript】javascript学习 二十四 JavaScript Date(日期)对象
    【Javascript】javascript学习 二十七 JavaScript Math(算数)对象
  • 原文地址:https://www.cnblogs.com/Zhangmin123/p/6263941.html
Copyright © 2011-2022 走看看