Java多线程编程基础之线程对象
在进入java平台的线程对象之前,基于基础篇(一)的一些问题,我先插入两个基本概念。
[线程的并发与并行]
在单CPU系统中,系统调度在某一时刻只能让一个线程运行,虽然这种调试机制有多种形式(大多数是时间片轮巡为主),但无论如何,要通过不断切换需要运行的线程让其运行的方式就叫并发(concurrent)。而在多CPU系统中,可以让两个以上的线程同时运行,这种可以同时让两个以上线程同时运行的方式叫做并行(parallel)。
在上面包括以后的所有论述中,请各位朋友谅解,我无法用最准确的词语来定义储如并发和并行这类术语,但我以我的经验能通俗地告诉大家它是怎么一回事,如果您看到我说的一些"标准"文档上说的不一样,只要意思一致,那您就不要挑刺了。
[JAVA线程对象]
现在我们来开始考察JAVA中线程对象。
在JAVA中,要开始一个线程,有两种方式。一是直接调用Thread实例的start()方法,二是
将Runable实例传给一个Thread实例然后调用它的start()方法。
在前面已经说过,线程对象和线程是两个完全不同的概念。这里我们再次深入一下,生成一个线程的实例,并不代表启动了线程。而启动线程是说在某个线程对象上启动了该实例对应的线程,当该线程结束后,并不会就立即消失。
对于从很多书籍上可以看到的基础知识我就不用多说了。既然是基础知识,我也着重于从普通文档上读不到的内容。所以本节我重点要说的是两种线程对象产生线程方式的区别。
class MyThread extends Thread{
public int x = 0;
public void run(){
for(int i=0;i<100;i++){
try{
Thread.sleep(10);
}catch(Exception e){}
System.out.println(x++);
}
}
}
如果我们生成MyThread的一个实例,然后调用它的start()方法,那么就产生了这个实例对应的线程:
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
}
}
不用说,最终会打印出0到99,现在我们稍微玩一点花样:
对应的线程:
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
System.out.println(101);
}
}
也不用说,在基础篇(一)中我们知道由于单CPU的原因,一般会先打印101,然后打印0到99。不过我们可以控制线程让它按我们的意思来运行:
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
mt.join();
System.out.println(101);
}
}
好了,我们终于看到,mt实例对应的线程(假如我有时说mt线程请你不要怪我,不过我尽量不这么说)。在运行完成后,主线程才打印101。因为我们让当前线程(这里是主线程)等待mt线程的运行结束。"在线程对象a上调用join()方法,就是让当前正在执行的线程等待线程对象a对应的线程运行完成后才继续运行。" 请大家一定要深刻理解并熟记这句话,而我这里引出这个知识点的目的是为了让你继续看下面的例子:
public class Test {
public static void main(String[] args) throws Exception{
MyThread mt = new MyThread();
mt.start();
mt.join();
Thread.sleep(3000);
mt.start();
}
}
当线程对象mt运行完成后,我们让主线程休息一下,然后我们再次在这个线程对象上启动线程。结果我们看到:
Exception in thread "main" java.lang.IllegalThreadStateException
也就是这种线程对象一时运行一次完成后,它就再也不能运行第二次了。我们可以看一下它有具体实现:
public synchronized void start() {
if (started)
throw new IllegalThreadStateException();
started = true;
group.add(this);
start0();
}
一个Thread的实例一旦调用start()方法,这个实例的started标记就标记为true,事实中不管这个线程后来有没有执行到底,只要调用了一次start()就再也没有机会运行了,这意味着:
[通过Thread实例的start(),一个Thread的实例只能产生一个线程]
那么如果要在一个实例上产生多个线程(也就是我们常说的线程池),我们应该如何做呢?这就是Runnable接口给我们带来的伟大的功能。
class R implements Runnable{
private int x = 0;
public void run(){
for(int i=0;i<100;i++){
try{
Thread.sleep(10);
}catch(Exception e){}
System.out.println(x++);
}
}
}
正如它的名字一样,Runnable的实例是可运行的,但它自己并不能直接运行,它需要被Thread对象来包装才行运行:
public class Test {
public static void main(String[] args) throws Exception{
new Thread(new R()).start();
}
}
当然这个结果和mt.start()没有什么区别。但如果我们把一个Runnable实例给Thread对象多次包装,我们就可以看到它们实际是在同一实例上启动线程:
public class Test {
public static void main(String[] args) throws Exception{
R r = new R();
for(int i=0;i<10;i++)
new Thread(r).start();
}
}
x是实例对象,但结果是x被加到了999,说明这10个线程是在同一个r对象上运行的。请大家注意,因为这个例子是在单CPU上运行的,所以没有对多个线程同时操作共同的对象进行同步。这里是为了说明的方便而简化了同步,而真正的环境中你无法预知程序会在什么环境下运行,所以一定要考虑同步。
到这里我们做一个完整的例子来说明线程产生的方式不同而生成的线程的区别:
package debug;
import java.io.*;
import java.lang.Thread;
class MyThread extends Thread{
public int x = 0;
public void run(){
System.out.println(++x);
}
}
class R implements Runnable{
private int x = 0;
public void run(){
System.out.println(++x);
}
}
public class Test {
public static void main(String[] args) throws Exception{
for(int i=0;i<10;i++){
Thread t = new MyThread();
t.start();
}
Thread.sleep(10000);//让上面的线程运行完成
R r = new R();
for(int i=0;i<10;i++){
Thread t = new Thread(r);
t.start();
}
}
}
上面10个线程对象产生的10个线程运行时打印了10次1。下面10个线程对象产生的10个线程运行时打印了1到10。我们把下面的10个线程称为同一实例(Runnable实例)的多个线程。
本文出自:
http://dev.yesky.com/186/2547686.shtml 2006-08-27 05:00作者:蒋涛 出处:bea责任编辑:方舟
分享到:
相关推荐
《汪文君JAVA多线程编程实战》是一本专注于Java多线程编程的实战教程,由知名讲师汪文君倾力打造。这本书旨在帮助Java开发者深入理解和熟练掌握多线程编程技术,提升软件开发的效率和质量。在Java平台中,多线程是...
《Java多线程编程实战指南》这本书深入浅出地讲解了Java多线程的核心概念和实战技巧,分为核心篇和设计模式篇,旨在帮助开发者掌握并应用多线程技术。 1. **线程基础** - **线程的创建**:Java提供了两种创建线程...
Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过`Thread`类和并发工具来实现,接下来我们将深入探讨这些关键知识点。 1. **...
Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的效率和响应性。在Java中,多线程主要通过继承Thread类或实现Runnable接口来实现。本教程将深入探讨Java多线程的各个方面...
这份“Java多线程编程指南”深入探讨了这一主题,为中级到高级的Java开发者提供了宝贵的资源。 首先,多线程的基础概念是理解整个主题的关键。线程是程序执行的最小单元,每个线程都有自己的程序计数器、虚拟机栈、...
《深入学习:Java多线程编程》是一本...通过学习《深入学习:Java多线程编程》,开发者可以提升在复杂并发环境下的编程能力,为开发高并发、高可用的应用打下坚实的基础。这本书无疑是Java开发者进阶必备的参考书之一。
总的来说,“Java多线程编程实例”这本书涵盖了Java多线程编程的各个方面,从基础概念到高级用法,包括线程创建、同步机制、线程池、线程通信以及并发工具类的使用,都是现代Java开发者必备的知识。虽然年代久远,但...
从给定的文件信息中,我们可以提取出关于Java多线程...以上是Java多线程编程的基础知识点,理解这些概念对于开发高效、健壮的多线程应用程序至关重要。通过实际操作和不断实践,可以更深入地掌握Java多线程编程的精髓。
Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,极大地提高了程序的...通过阅读这本书,开发者可以深入理解Java多线程编程的核心概念,提升自己的编程能力,为应对复杂并发场景打下坚实基础。
Java多线程编程是Java开发中的重要组成部分,它允许...通过学习和实践"Java多线程编程核心技术.zip"中的内容,开发者能深入理解Java多线程的原理和应用,提升软件并发处理能力,为构建高效、稳定的应用打下坚实基础。
《Java多线程编程实例》这本书深入浅出地探讨了Java中的多线程编程,通过丰富的实例帮助读者理解和掌握这一复杂主题。随书源码提供了实际操作的机会,以便读者能够亲手实践书中的示例,加深理解。 1. **线程创建...
### Java多线程编程详解:深入理解与实践 #### 一、理解多线程机制 多线程,作为现代编程语言的重要特性之一,允许在单一应用程序内...掌握Java多线程编程的精髓,将为构建高性能、高可用性的应用打下坚实的基础。
随着现代处理器的生产工艺从提升...《Java多线程编程实战指南(核心篇)》适合有一定Java语言基础的读者作为入门多线程编程之用,也适合有一定多线程编程经验的读者作为重新梳理知识结构以提升认知层次和参考之用。
在Java编程中,多线程是一项关键技能,它允许程序同时执行多个任务,极大地提高了程序的...通过阅读"Java多线程编程实战指南 设计模式篇.pdf",你将获得更深入的理论知识和实践技巧,为你的编程事业奠定坚实的基础。
Java 多线程编程基础知识 Java 多线程编程精要之基础 Java 教程是 Java 程序中运用多线程的基本教程,旨在帮助用户快速掌握 Java 多线程编程的基础知识。本教程通过简洁的编程示例来说明 Java 程序中的多线程是多么...
在本文中,我们将深入探讨Java多线程编程的基础知识和高级技术。 什么是多进程和多线程? 在计算机科学中,进程(Process)和线程(Thread)是两种不同的概念。进程是操作系统中的一种基本执行单元,具有独立的...
了解这些状态对于掌握Java多线程编程至关重要。 新建状态是指线程对象创建之后,此时线程尚未开始运行。就绪状态表示线程已经准备好运行,但CPU尚未分配时间片给它。运行状态是指线程获得CPU时间片后开始执行的过程...
Java多线程编程是Java开发中的重要组成部分,它允许程序同时执行多个任务,提升系统效率。在本实例源码中,包含17个章节和上百个实例,旨在深入讲解Java多线程的核心概念和实际应用。 一、线程基础知识 在Java中,...
总之,Java多线程编程涉及线程的创建、同步、通信以及异常处理等多个方面,理解和熟练掌握这些知识点是编写高效并发程序的基础。在实际开发中,应根据项目需求和性能优化选择合适的多线程实现策略。