`

Java多线程编程初步

阅读更多
什么是多线程编程

  多线程编程技术是Java语言的重要特点。多线程编程的含义是将程序任务分成几个并行的子任务。特别是在网络编程中,你会发现很多功能是可以并发执行的。比如网络传输速度较慢、用户输入速度较慢,你可以用两个独立的线程去完成这两个功能,而不影响正常的显示或其它功能。
多线程是与单线程比较而言的,普通的Windows采用单线程程序结构,其工作原理是:主程序有一个消息循环,不断从消息队列中读入消息来决定下一步所要干的事情,一般是针对一个函数,只有等这个函数执行完之后,主程序才能接收另外的消息来执行。比如子函数功能是在读一个网络数据,或读一个文件,只有等读完这个数据或文件才能接收下一个消息。在执行这个子函数过程中你什么也不能干。但往往读网络数据和等待用户输入有很多时间处于等待状态,多线程利用这个特点将任务分成多个并发任务后,就可以解决这个问题。
Java中的线程类

  要学会Java中的多线程编程,就得知道如何实现支持多线程的类。Java中实现多线程的类有两种方法:

  1.扩展java.lang.Thread类,用它覆盖Thread类的run方法。

  2.生成实现java.lang.Runnable接口的类并将其它的实例与java.lang.Thread实例相关联。

  Thread类是负责向其它类提供线程支持的最主要的类,要使用一个类具有线程功能,在Java中只要简单地从Thread类派生一个子类就可以了扩展Thread类,如printThread.java。

  下面我们将通过实例来介绍如何使用这两种方法编写自己的多线程应用程序。

  创建java.lang.Thread类的子类

  Thread类最重要的方法是run方法。run方法是新线程执行的方法,因此生成java.lang.Thread的子类时,必须有相应的run方法。

//PrintThread.java
public class PrintThread extends Thread//继承Tread类
private int count=0 //定义一个count变量用于统计打印的次数并共享变量
public static void mainString args//main方法开始
PrintThread p=new PrintThread//创建一个线程实例
p.start//执行线程
for{;;}//主线程main方法执行一个循环,for执行一个死循环

count++
System.out.printcount+″:Main/n″//主线程中打印count +“main”变量的值,并换行

public void run//线程类必须有的run()方法
for{;;}

count++
System.out.printcount+″:Thread/n″


  上面这段程序便是继承java.lang.Tread并覆盖run的方法。用Java 虚拟机启动程序时,这个程序会先生成一个线程并调用程序主类的main方法。这个程序中的main方法生成新线程,连接打印“Thread”。在启动线程之后,主线程继续打印“Main”。

  编译并执行这个程序,然后立即按“Ctrl+C”键中断程序,你会看到上面所述的两个线程不断打印出:XXX:main…..XXX:Thread…. XXX代表的是数字,也就是上面count的值。在笔者的机器上,不同时刻这两个线程打印的次数不一样,先打印20个main(也就是先执行20次主线程)再打印出50次Thread,然后再打印main……

  提示:为了便于查看该程序的执行结果,你可以将执行结果导入一个文本文件,然后打开这个文件查看各线程执行的情况。如运行:

javac PrintThread.java
Java PrintThread>1.txt

  第一个命令javac PrintThread.java是编译java程序,第二个是执行该程序并将结果导入1.txt文件。这样,打开这个文件,你就可以看见详细的结果了(注意:程序的执行时间不能太长,不然生成的1.txt文件会很庞大)。当然你可以直接执行命令:java PrintThread。

实现java.lang.Runnable接口

  运行线程的另一种方法是实现Runnable接口,然后生成运行这个类的线程即可。Runnable接口是定义在java.lang包中的一个接口,其中只提供了一个抽象的run声明。

  下面我们来看看如何实现Runnable接口,而不是扩展Thread类。

//PrintRunnableThread.java 实现Runnable接口
public class PrintRunnableThread implements Runnable
public static void mainString args
Thread t=new Threadnew PrintRun
nableThread
//t.setPriorityThread.MAX_PRIORI
TY//设置最大优先级
t.start//线程开始
for{;;}//不停地打印字符M,代表主线程main
System.out.println″M″

public void run
for{;;}//不停地打印字符T,代表线程thread
System.out.println″T″

  运行本程序,你会发现执行结果和PrintThread.java的执行结果很类似,甚至你可以再添加一个变量,并打印出相似的线程执行结果。

  提示:与前例不同的是,如果去掉t.setPriorityThread.MAX_PRIORITY语句前的注释符,就将线程设置成最大优先级,执行结果就大不一样了。

  线程组ThreadGroup

  java.lang.ThreadGroup类表示一组线程(可能包含其它ThreadGroup),用来实现按照特定功能对线程进行集中式分组管理。用户创建的每个线程均属于某线程组,这个线程组可以在线程创建时指定,也可以不指定线程组以使该线程处于默认的线程组之中。但是,一旦线程加入某线程组,该线程就一直存在于该线程组中直至线程终止,不能在中途改变线程所属的线程组。

  下面的代码演示了如何操作和使用ThreadGroup。

//ThreadGroupTest.java
public class ThreadGroupTest implements Runnabl
e
public void run

public static void main(String args[])
//生成一个新的线程组,并将两个线程对象放到该线程组里。
ThreadGroup threadgroup=new ThreadGroup″线程组″
Thread t1=new Threadthreadgroupnew ThreadGrou
pTest″线程 1″
Thread t2=new Threadthreadgroupnew ThreadGrou
pTest″线程 2″
//找到顶级的父线程
ThreadGroup parent=Thread.currentThread.getThrea
dGroup//得到当前线程的线程组
whileparent.getParent=null

parent=parent.getParent//得到父线程

//list方法打印出当前线程组的所有内容线程和子线程组
parent.list

  提示:上段程序中,list()方法显示ThreadGroup树(可能包括线程和线程组,所以构成了线程树)的结构和内容。运行上面程序你就会对线程组有了一定的了解。

线程优先级

  虽然我们说线程是并发运行的。然而事实常常并非如此。当系统中只有一个CPU时,以某种顺序在单CPU情况下执行多线程被称为调度scheduling。Java采用的是一种简单、固定的调度法,即固定优先级调度。这种算法是根据处于可运行线程的相对优先级来实行的。当线程产生时,它继承原线程的优先级。在需要时可对优先级进行修改。在任何时刻,如果有多条线程等待运行 系统选择优先级最高的可运行线程运行。只有当它停止、自动放弃、或由于某种原因成为非运行状态优先级的线程时才能运行。如果两个线程具有相同的优先级它们将被交替地运行。

  Java中的第一个线程都有优先级,线程的优先级是介于Thead.MIN_PRIORITY到Thread.MAX_PRIORITY之间的整数介于0到10之间。缺省情况下,线程的优先级是5即NORM_PRIORITY。我们可以用形如Thread.setPriorityThread.MIN_PRIORITY这样的表达式来设置线程的优先级稍后会在例程中用到。也可以通过getPriority来得到线程的优先级,还可以通过setPriority在线程创建之后的任意时间改变线程的优先级。

  提示:当线程中的代码创建一个新线程对象时,这个新线程拥有与创建它的线程一样的优先级。

  线程的管理

  单线程的程序都有一个main执行体,它运行一些代码,当程序结束执行后,程序结束运行。在Java中我们要得到相同的应答,必须稍微进行改动。只有当所有的线程退出后,程序才能结束。只要有一个线程一直在运行,程序就无法退出。

  线程包括new()开始、running()运行、wait()等候和done结束执行状态。第一次创建线程时,都位于new状态,在这个状态下,不能运行线程,只能等待。这时,线程要么调用start方法开始运行,要么送往done状态结束。位于done中的线程已经结束执行,这是线程的最后一个状态。一旦线程位于这个状态,就不能再次出现,而且当Java虚拟机中的所有线程都位于done状态时,程序就强行中止。

  当前正在执行的所有线程都位于running状态,在程序之间用某种方法把处理器的执行时间分成时间片。位于running状态的每个线程都是能运行的,但在一个给定的时间内,每个系统处理器只能运行一个线程。与位于running状态的线程不同,由于某种原因,可以把已经位于waiting状态的线程从一组可执行线程中删除。如果线程的执行被中断,就回到waiting状态。这时,线程可能被挂起,在系统资源上等候,或者被告知进入休眠状态Sleep。该状态的线程可以返回到running状态,也能由stop送入done状态。Thread类提供了Sleep()、Stop、Yield()、Suspend()和Resume()等方法来管理线程。

  线程操作的其它概念

  通过这期两个程序的学习,可能你会认为Java的线程操作很简单,但实事并非如此。在实际工作中,可能需要综合考虑很多问题,比如设置监控线程、暂停、命名和协调线程、设置线程的优先级、共享变量、线程同步、线程池、线程组等。对于这些线程相关的操作,笔者不在本章中详细讲述了。如果读者有兴趣,可参考相应的专著,毕竟这部分不是一两篇文章可以完全讲解完的。

分享到:
评论

相关推荐

    汪文君高并发编程实战视频资源下载.txt

    │ 高并发编程第一阶段05讲、采用多线程方式模拟银行排队叫号.mp4 │ 高并发编程第一阶段06讲、用Runnable接口将线程的逻辑执行单元从控制中抽取出来.mp4 │ 高并发编程第一阶段07讲、策略模式在Thread和Runnable...

    Java多线程文章系列.pdf

    #### 一、Java多线程编程详解 ##### 1. 理解多线程 - **定义**: 多线程是一种机制,允许程序中并行执行多个指令流,每个指令流称为一个线程。 - **特点**: - 线程拥有独立的执行控制,由操作系统负责调度。 - ...

    C#Socket多线程编程实例[收集].pdf

    C# Socket 多线程编程实例 C# 是微软随着 VS.net 新推出的语言,它具有 C++ 的强健和 VB 等的 RAD 特性。微软推出 C# 主要是为了对抗 Sun 公司的 Java。C# 在网络编程方面也自然不甘落后于人。这篇文章主要介绍 C# ...

    Java游戏编程初步

    总的来说,Java游戏编程初步会引导初学者理解Applets的开发流程、线程的概念及其在游戏中的应用,为进一步深入Java游戏开发打下基础。虽然这个领域可能需要更多的学习,如图形库、物理引擎和网络编程,但这个起点为...

    汪文君高并发编程实战视频资源全集

    │ 高并发编程第一阶段05讲、采用多线程方式模拟银行排队叫号.mp4 │ 高并发编程第一阶段06讲、用Runnable接口将线程的逻辑执行单元从控制中抽取出来.mp4 │ 高并发编程第一阶段07讲、策略模式在Thread和Runnable...

    java游戏编程初步

    ### Java游戏编程初步:探索游戏开发的奇妙世界 在当今的游戏开发领域,C和C++似乎是主导语言,尤其是在大型和复杂游戏的制作中。然而,Java作为一种新兴且多功能的编程语言,同样具备游戏开发的强大潜力,尽管这一...

    java游戏编程初步.doc

    ### Java游戏编程初步知识点概述 #### 一、Java在游戏编程中的潜力 - **Java语言特点**:作为一种相对较新的编程语言,Java具有诸多优势,比如跨平台性、内存管理自动化等,这些特性使得Java在游戏开发领域具备...

    初步了解java编程语言

    - Java内置对多线程的支持,可以通过实现Runnable接口或继承Thread类创建线程。 - 线程同步机制包括synchronized关键字、wait(), notify(), notifyAll()方法以及Lock接口。 8. **网络编程**: - Java提供了...

    Java并发编程实践源码

    《Java并发编程实践》是一本深入探讨Java多线程与并发编程的经典著作,其源码提供了丰富的示例,帮助读者理解和应用并发编程的核心概念。在这些文件中,我们可以看到多种并发设计模式和策略的实际运用,下面将逐一...

    清华大学JAVA编程语言

    第八讲:多线程编程 介绍并发编程,包括线程的创建、同步与通信,理解多线程在提升程序效率中的作用。 第九讲:JAVA反射与注解 讲解JAVA反射机制,如何在运行时动态获取类的信息和调用方法,以及注解的使用,理解其...

    精通Java网络编程第二版

    Java网络编程是Java开发中的重要组成部分,它涵盖了网络通信的基础概念、TCP/IP协议族、套接字编程、多线程、网络安全以及相关API的使用。本书第二版在第一版的基础上进行了更新和完善,以适应现代网络技术的发展。 ...

    Java游戏编程

    Java的Swing和JavaFX库可以用于构建游戏界面,而Java的并发处理能力则有助于管理多线程游戏逻辑,确保游戏流畅运行。 在Java游戏中,图形渲染是关键的一部分。Java可以利用Java 2D API进行2D游戏开发,它提供了一...

    java编程逻辑

    7. **多线程**:理解并发编程的基础,如线程的创建、同步机制(synchronized关键字,wait/notify方法)以及线程池。 8. **枚举和注解**:Java中的枚举类型以及注解的使用,它们在代码中起到规范和元数据的作用。 9...

    语言程序设计资料:Java游戏编程初步.doc

    线程同步也是关键,例如使用`synchronized`关键字、`wait()`和`notify()`方法来防止数据竞争,确保多线程环境下的正确性。 除了以上基础,Java游戏编程还涉及到图形库(如Java AWT和Swing)、事件处理、动画制作、...

    Java线程(20210930172753).pdf

    结合上述知识点,可以推测该文档是关于Java多线程编程的基础教学内容,涵盖了线程创建、启动、接口实现、线程生命周期、以及线程安全的初步介绍。对于Java开发者来说,这些知识点是构建并发应用程序的基石。

    Java高级编程教案

    1. **多线程**:Java提供了强大的多线程支持,通过Thread类和Runnable接口实现。学习如何创建、控制和管理线程,理解同步和互斥的概念,以及死锁和活锁的避免,是成为优秀Java开发者的基础。 2. **网络编程**:Java...

    java游戏编程资料

    这部分内容可能涵盖了网络通信协议(如TCP/IP)、多线程编程以处理并发玩家、游戏服务器架构、数据存储与同步、游戏对象的状态管理等。通过实际项目实践,学习者将能更深入地理解如何构建可扩展、稳定且具有实时性的...

Global site tag (gtag.js) - Google Analytics