拨开云雾见天日 —— Java多线程编程概念剖析

说到Java多线程编程,大多数人都会想到继承Thread或实现Runnable编程,new 一个Thread实例,调用start()方法,由OS调用即可。具体过程如下:

public class MyThread extends Thread {

    @Override
    public void run() {
        System.out.println("MyThread");
    }

    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
        System.out.println("运行结束!");
    }}

继承Thread;

public class MyRunnable implements Runnable {

    @Override
    public void run() {
        System.out.println("MyRunnable");
    }

    public static void main(String[] args) {
        Thread thread = new Thread(new MyRunnable());
        thread.start();
        System.out.println("运行结束!");
    }}

实现Runnable;

这里,有一个问题,就是无论继承Thread还是实现Runnable,最后都需要有一个Thread实例,来激活线程。那么,这个实例化的Thread实例是什么呢?仅仅代表一个线程。如果是这样,那么实现了Runnable的对象有代表什么,它与Thread有何不同?让我们来仔细看看Java线程。

Java线程

线程,就是进程中独立运行的子任务。通常理解为轻量级进程,多个线程共享一个进程资源。由于线程是由OS分配与调度,因此容易产生资源竞争问题,所以成为整个多线程开发中的难点。

从对线程概念的理解上,可以看到,真正线程应该有两个概念,(线程)任务和(线程)调度。

线程任务

再来看看线程代码。无论继承Thread还是实现Runnable,都需要重写一个run()方法,这里面的代码,是线程执行时真正要执行的方法,也就是说,这是线程任务。没任务,线程干嘛?自己玩!!!肯定不可以。

从Runnable接口来看,它只有一个声明——run,也就是说,你要为它的实现类指派任务。之所以有Runnable接口,一方面是因为Java是单继承,不可能为了线程继承了Thread还去继承其他类,所以必须要有Runnable。第二,从面向对象设计原则——单一职责来看,一个类只负责某一方面的任务就可以了,避免引入多变量,多变量代表多不确定性,失控的机会会加大。所以需要Runnable的存在,只负责指派线程任务。

Thread也是存在run抽象方法的,它本身就是代表线程(具体哪个暂时不说)。由它实例自己然后自己激活也是可以的,要不然,只有一个激活而没有任务,怎么也说不过去。其实Thread也是实现Runnable,自己的任务还参考别人的……

    public static void main(String[] args) {
        MyThread thread = new MyThread();
        thread.start();
        System.out.println("运行结束!");
    }

这个MyThread继承自Thread类,并(暗藏)重写了run()方法。没任务玩什么!!!

线程调度

有了任务,就要有人执行,就需要有调度。是谁?就是开篇问到的那个问题。两种方式的线程都需要有一个Thread实例,这就是线程调度。

对于继承式的线程,我们好理解,自己激活自己的任务,那么对于实现式的线程呢,是怎么激活的?

在Thread中,有一个Thread(Runnable target)构造方法,也就是说在Thread里有一个Runnable变量。对此,Thread里是这样注释的:“ What will be run.”。再看看Thread的调度代码:

@Override
public void run() {
     if (target != null) {
         target.run();
    }}

target就是Runnable实例,也就是先看看有没有单独的任务表(可以把Runnable看做是一个任务表),如果没有,再查看自己的任务。

那么,现在就很明显了,Thread类其实更重的职责在于线程调度(虽然也可以指派任务),Runnable是用来指派线程任务。在多线程编程中,有关竞争、安全、同步这种资源处理的问题,都发生在线程任务身上。看看同步关键字synchronized和Thread一点关系都没有。如果不指定锁,那么默认的锁对象就是任务实例。有关状态、优先、通信等,真正涉及到线程本身的运行,这些才是线程调度处理的问题。

线程与共享

为了进一步说明线程任务与线程调度,这里再给出一个常见的线程变量共享例子:

public class MyThread extends Thread {
    private int count = 5;

    public MyThread(){}

    /** 设置线程名称 */
    public MyThread(String name){
        this.setName(name);
    }

    @Override
    public void run() {
        while(count>0){
            count -- ;
            System.out.println("由 " + this.currentThread().getName() + " 计算,count:= " +count);
        }
    }

    public static void main(String[] args) {
        MyThread thread = new MyThread();
        Thread a = new Thread(thread, "A");
        Thread b = new Thread(thread, "B");
        Thread c = new Thread(thread, "C");
        a.start();
        b.start();
        c.start();
    }}

运行结果如下(不同时刻运行结果不一样):

这里没考虑安全问题。 可以看到,这里三个线程调度器共同执行一个任务,才能实现线程变量共享:线程调度器A操作改变count值,然后线程调度器B接着操作改变count……

以上就是对Java线程编程概念的初步理解……

时间: 2024-10-03 13:14:26

拨开云雾见天日 —— Java多线程编程概念剖析的相关文章

Java多线程编程— 概念以及经常使用控制

多线程能满足程序猿编写很有效率的程序来达到充分利用CPU的目的,由于CPU的空暇时间可以保持在最低限度.有效利用多线程的关键是理解程序是并发运行而不是串行运行的.比如:程序中有两个子系统须要并发运行,这时候就须要利用多线程编程. 线程的运行中须要使用计算机的内存资源和CPU. 一.    进程与线程的概念 这两者的概念,这里仅仅给出自己狭隘的理解: 进程:进程是一个独立的活动的实体,是系统资源分配的基本单元. 它能够申请和拥有系统资源. 每一个进程都具有独立的代码和数据空间(进程上下文). 进程

Java多线程编程— 概念以及常用控制

多线程能满足程序员编写非常有效率的程序来达到充分利用CPU的目的,因为CPU的空闲时间能够保持在最低限度.有效利用多线程的关键是理解程序是并发执行而不是串行执行的.例如:程序中有两个子系统需要并发执行,这时候就需要利用多线程编程.线程的运行中需要使用计算机的内存资源和CPU. 一.    进程与线程的概念 这两者的概念,这里只给出自己狭隘的理解: 进程:进程是一个独立的活动的实体,是系统资源分配的基本单元.它可以申请和拥有系统资源.每个进程都具有独立的代码和数据空间(进程上下文).进程的切换会有

Java多线程编程(学习笔记)

一.说明 周末抽空重新学习了下多线程,为了方便以后查阅,写下学习笔记. 有效利用多线程的关键是理解程序是并发执行而不是串行执行的.例如:程序中有两个子系统需要并发执行,这时候需要利用多线程编程. 通过多线程的使用,可以编写出非常高效的程序.但如果创建了太多的线程,程序执行的效率反而会降低. 同时上下文的切换开销也很重要,如果创建太多的线程,CPU花费在上下文的切换时间将对于执行程序的时间. 二.Java多线程编程 概念 在学习多线程时,我们应该首先明白另外一个概念. 进程:是计算机中的程序关于某

Java多线程编程总结一:多线程基本概念

Java多线程编程总结一 – 初识多线程 进程.多进程.线程.多线程的概念 进程(process):CPU的执行路径.通俗的说就是系统中正在运行的程序.比如我们打开了浏览器.QQ等等,这些程序一旦被打开运行了,就是所谓的进程. 多进程:系统中同时运行的多个程序.这个我们应该不难理解了,在打开浏览器的同时我们也可以QQ聊天.CS单机游戏等. 线程(thread):运行在进程中的运行单元.比如迅雷下载中我们的某一个下载任务就是一个线程. 多线程:同理可知,每个进程里面有多个独立的或者相互有协作关系的

汪大神Java多线程编程实战

课程目录:├─1│  ├─Java并发编程.png│  ├─源码+ppt.rar│  ├─高并发编程第一阶段01讲.课程大纲及主要内容介绍.wmv│  ├─高并发编程第一阶段02讲.简单介绍什么是线程.wmv│  ├─高并发编程第一阶段03讲.创建并启动线程.mp4│  ├─高并发编程第一阶段04讲.线程生命周期以及start方法源码剖析.mp4│  ├─高并发编程第一阶段05讲.采用多线程方式模拟银行排队叫号.mp4│  ├─高并发编程第一阶段06讲.用Runnable接口将线程的逻辑执行单元

《Java多线程编程核心技术》推荐

写这篇博客主要是给猿友们推荐一本书<Java多线程编程核心技术>. 之所以要推荐它,主要因为这本书写得十分通俗易懂,以实例贯穿整本书,使得原本抽象的概念,理解起来不再抽象. 只要你有一点点Java基础,你就可以尝试去阅读它,相信定会收获甚大! 博主之前网上找了很久都没完整pdf电子版的,只有不全的试读版,这里博主提供免费.清晰.完整版供各位猿友下载: http://download.csdn.net/detail/u013142781/9452683 刚刚已经提到,<Java多线程编程核

java多线程基本概念与简单实用

概述 程序:Program,是一个静态的概念 进程:Process,是一个动态的概念 进程是程序的一次动态执行过程, 占用特定的地址空间.每个进程都是独立的,由3部分组成cpu,data,code 缺点:内存的浪费,cpu的负担 线程:Thread,是进程中一个"单一的连续控制流程"  (a single sequential flow ofcontrol)/执行路径.线程又被称为轻量级进程(lightweight process). 一个进程可拥有多个并行的(concurrent)线

Java多线程编程基础之线程对象

在进入java平台的线程对象之前,基于基础篇(一)的一些问题,我先插入两个基本概念. [线程的并发与并行] 在单CPU系统中,系统调度在某一时刻只能让一个线程运行,虽然这种调试机制有多种形式(大多数是时间片轮巡为主),但无论如何,要通过不断切换需要运行的线程让其运行的方式就叫并发(concurrent).而在多CPU系统中,可以让两个以上的线程同时运行,这种可以同时让两个以上线程同时运行的方式叫做并行(parallel). 在上面包括以后的所有论述中,请各位朋友谅解,我无法用最准确的词语来定义储

Java多线程编程详解

线程的同步 由于同一进程的多个线程共享同一片存储空间,在带来方便的同时,也带来了访问冲突这个严重的问题.Java语言提供了专门机制以解决这种冲突,有效避免了同一个数据对象被多个线程同时访问. 由于我们可以通过 private 关键字来保证数据对象只能被方法访问,所以我们只需针对方法提出一套机制,这套机制就是 synchronized 关键字,它包括两种用法:synchronized 方法和 synchronized 块. 1. synchronized 方法:通过在方法声明中加入 synch