从计算机操作系统的发展来看,经历了这样的两个阶段:
单进程处理:最传统的DOS 系统中只要有病毒出现,则立刻有反映,因为在DOS 系统中属于进程处理,即:在同一个时间段上只能有一个程序在执行
多进程处理:windows操作系统是一个多进程,例如,假设在windows 中出现病毒了,则系统照样可以使用
那么对于资源来讲,所有IO设置、CUP等等都只有一个,那么对于多进程的处理来讲,在同一个时间段上会有多个程序运行,但是在同一个时间点上只能有一个程序运行
线程是在进程基础上的进一步划分,举个不恰当的例子来说:word 中的拼写检查,是在word整个程序运行中运行的。
所以,如果进程,则线程就消失,而如果线程消失的话,则进程依然会执行,未必会消失。
Java 本身是属于多线程的操作语言,所以提供了线程的处理机制。
线程实现的两种方式
在Java 中可以有两种方式实现多线程操作,一种是继承Tread类,另外一种是实现Runnable 接口
Thread 类
Thread 类是在java.lang 包中定义
一个类只要继承了Thread类,同时覆写了本类中的run()方法,则就可以实现多线程的操作了
package org.threaddemo;
public class MyThread extends Thread{
private String name; //定义name 属性
public MyThread(String name){
this.name = name;
}
public void run(){ //覆写run()方法
for (int i=0;i<50;i++){ // 表示循环50次
System.out.println("Thread 测试"+this.name+" i:"+i);
}
}
}
以上的类已经完成了多线程的操作类,那么下面就启动线程
package org.threaddemo;
public class ThreadDemo02 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread th1 = new MyThread("A类");
MyThread th2 = new MyThread("B类");
th1.run();
th2.run();
}
}
但是,此时的执行可以发现非常的有规律,先执行完第一个对象,再执行第二个对象,也就是说并没有实现交互的运行
从JDK的文档中可以发现,一旦调用strat()方法,则会通过JVM找到run()方法
public void start()
package org.threaddemo;
public class ThreadDemo02 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread th1 = new MyThread("A类");
MyThread th2 = new MyThread("B类");
th1.start();
th2.start();
}
}
此时,程序已经可以正常的进行交互式的运行了。
但是,需要思考的是,为什么非要使用start()方法启动多线程呢?
在JDK 的安装路径下,src.zip是全部的java 源程序,通过此代码找到 Thread 类中的 start()方法的定义:
public synchronized void start(){ //定义的start()方法
if (started) //判断线程是否已经启动
throw new IllegalThreadStateException();
started = true;//如果没有启动则修改状态
start0();//调用start0()方法
}
private native void start0(); //使用 natvie 关键字声明的方法,没有方法体
操作系统有很多种,Windows、Linux、UNIX,既然多线程操作中要进行CPU资源的强占,也就是说要等待CPU调度,那么这些调度的操作是由各个操作系统的低层实现的,所以在java程序中根中就没法实现,那么此时Java的设计者定义了native 关键字,使用此关键字表示可以调用操作系统的低层函数,那么这样的技术又称为JNI技术(Java Native Interface)
而且,此方法在执行的时候将调用run()方法完成,由系统默认调用的
但是,第一种操作中有一个最大的限制,一个类只能继承一个父类
Runnable 接口
在实际的开发中一个多线程的操作类很少去使用Thread 类完成,而是通过Runnable 接口完成。
观察Runnable 接口的定义:
public interface Runnable{
public void run();
}
所以,一个类只要实现了此接口,并覆写 run()方法
package org.threaddemo;
public class RunnableDemo implements Runnable{ //实现Runnable 接口
private String name; // 定义name 属性
public RunnableDemo(String name){
this.name = name;
}
public void run(){ //覆写run()方法
for (int i=0;i<50;i++){ //表示循环10次
System.out.println("Thread 测试"+this.name+" i:"+i);
}
}
}
完成之后,下面继续启动多线程
但在现在使用Runnable 定义的子类中并没有start()方法,而只有Thread类中才有
在Thread 类中存在以下的一个构造方法:
public Thread(Runnable target)
此构造方法接收Runnable 的子类实例。也就是说现在可以通过Thread 类中启动 Runnable 实现的多线程
package org.threaddemo;
public class ThreadDemo02 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
MyThread th1 = new MyThread("A类");
MyThread th2 = new MyThread("B类");
new Thread(th1).start(); //调用线程体
new Thread(th2).start(); //调用线程体
}
}
以上的操作代码也属于交替的运行,所以此时程序也同样实现了多线程的操作
两种实现方式的区别及联系
在程序的开发中只要是多线程则肯定永远以实现Runnable 接口为正统操作,因为实现Runnable 接口相比继承 Thread 类有如下的好处
避免单继承的局限,一个类可以同时实现多个接口
适合于资源的共享
以卖票的程序为例
public class TicketsDemo extends Thread { //继承 Thread
private int TiceketsDemo = 5; // 一共才5张票
public void run(){ //覆写 run()方法
for (int i=0;i<50;i++){ //表示循环50次
if (this.TiceketsDemo>0){
System.out.println("出票:"+this.TiceketsDemo--);
}
}
}
}
下面建立三个线程对象,同时卖票
package org.threaddemo;
public class ThreadDemo03 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
TicketsDemo tic1 = new TicketsDemo(); //一个线程
TicketsDemo tic2 = new TicketsDemo(); //一个线程
TicketsDemo tic3 = new TicketsDemo(); //一个线程
tic1.start(); //开始卖票
tic2.start(); //开始卖票
tic3.start(); //开始卖票
}
}
发现现在一共买了15张票,但是实际上只有5张票。所以证明每一个线程都买自己的票,没有达到资源共享的目的
那么,如果现在实现的是Runnable 接口的话,则就可以实现资源的共享:
package org.threaddemo;
public class ThreadDemo03 {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
TicketsDemo tic1 = new TicketsDemo();
new Thread(tic1).start();
new Thread(tic1).start();
new Thread(tic1).start();
}
}
虽然现在程序中有三个线程,但是三个线程一共才卖出了5张票。也就是说使用Runnable 实现的多线程可以达到资源共享的目的。
实际上 Runnable 接口和Thread 类之间还是存在联系的:
public class Thread extends Object implements Runnable
发现Thread 类也是Runnable 接口的子类
分享到:
相关推荐
"JAVA线程与进程的区别" JAVA语言中,线程(Thread)和进程(Process)是两个基本概念,它们都是操作系统所体会的程序运行的基本单元,系统利用该基本单元实现系统对应用的并发性。但是,它们之间有着本质的区别。 ...
2. **线程的启动与生命周期**:通过调用Thread对象的start()方法启动线程,线程会经历新建(New)、就绪(Runnable)、运行(Running)、等待/阻塞(Blocked/Wait)和终止(Terminated)五个状态。 3. **线程同步**...
本文中,我们还提供了一些相关的Java多线程编程资源,例如《Java进程与线程操作技巧总结》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》等。这些资源可以帮助读者更好地理解和掌握Java多线程编程的...
综上所述,这个“JAVA进程管理模拟”项目涵盖了Java进程与线程管理、图形用户界面设计、事件驱动编程和线程同步等多个核心知识点。通过这个项目,开发者不仅可以深入理解这些概念,还能直观地观察到它们在实际应用中...
了解和掌握进程与线程的区别和交互机制,对于编写高效的多线程程序至关重要。通过互斥锁和信号量等同步工具,我们可以有效地控制线程的并发访问,确保程序的正确性和性能。在实际开发中,合理地使用进程和线程,结合...
为了获取这些信息,我们可以使用jstack工具,它是Java开发工具包(JDK)的一部分,能够输出Java进程的线程堆栈跟踪信息。 jstack命令通常可以输出以下类型的信息: 1. 线程的完整堆栈跟踪,包括本地方法。 2. 显示...
在计算机科学中,程序、进程和线程是操作系统的基础概念,尤其在Java编程语言中,理解和掌握这些概念对于开发高效、并发的软件至关重要。本文将深入探讨Java的多线程特性,以及程序、进程和线程的基本定义和它们之间...
"操作系统中的进程、线程与Java的多线程" 操作系统中的进程是指特定的代码序列在指定数据集上的一次执行活动,是指并行程 序的的一次执行过程。在Windows 95中,就是一个EXE文件的执行过程。这是一个动态概念,具有...
在计算机科学领域,进程与线程是操作系统中最基础且至关重要的概念。进程是程序执行时的一个实例,每个进程都有自己的独立内存空间,包括代码、数据、堆栈等资源。线程则是进程内的一个执行单元,它共享进程的内存...
进程和线程是计算机操作系统中的两个基本概念,对于任何软件开发者,尤其是系统级或服务器...通过阅读“进程和线程.doc”文档,可以进一步深入学习这两个主题的细节,包括它们的生命周期、调度策略、同步与通信方法等。
#### 一、Java进程与线程概述 在Java中,一个JVM(Java虚拟机)实例本质上就是一个进程。进程在Java中由`java.lang.Process`类表示,它允许Java程序与操作系统进行交互,执行外部程序。进程间的数据空间是完全隔离...
Java多线程与并发编程是Java开发中至关重要的一部分,它涉及到如何高效地利用CPU资源,以实现程序的并行执行。在操作系统层面,多任务和多进程是通过分配不同的内存空间来实现的,而线程则共享同一进程的内存,这...
`bin`目录可能包含编译后的可执行文件或脚本,用于启动和管理这些Java进程。为了深入了解实现细节,需要查看源代码并理解其逻辑。 总的来说,Java实现守护进程、监听进程以及管理多个进程和JVM涉及多线程、网络编程...
Java并发编程是Java开发中的重要领域,涉及到进程与线程的概念,这两个概念是理解多任务执行的基础。在现代计算机系统中,进程和线程被广泛用于实现高效的资源管理和任务调度。 **1. 进程** 进程是操作系统分配...
本文将详细探讨Java中的线程和进程的区别,以及它们在程序设计和运行时的角色和重要性 理解线程和进程的区别对于Java程序员来说至关重要。线程提供了一种高效的方式来实现并发执行,而进程则是操作系统资源分配的...
更多java相关内容感兴趣的读者可查看本站专题:《Java进程与线程操作技巧总结》、《Java数据结构与算法教程》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》希望本文所...
《JAVA多线程设计模式》PDF 下载 《Java线程 高清晰中文第二版》中文第二版(PDF) 前言 第一章 线程简介 Java术语 线程概述 为什么要使用线程? 总结 第二章 Java线程API 通过Thread类创建线程 使用Runable接口...