一、什么是线程?什么是进程?两者有何区别?
每个Java程序都至少有一个线程——主线程。当一个Java程序启动时,JVM会创建主线程,并在该线程中调用程序的main()方法。线程可以理解为“程序内部的一个独立运行单位”。
进程是操作系统环境中的基本成分,是系统资源分配的基本单位。进程在执行过程中有内存单元的初始入口点,并且进程存活过程中始终拥有独立的内存地址空间。
两者的区别是:
1.简单而言,一个应用程序就是一个进程,而线程是一个进程内部的多个运行单位。
2.多个进程的内部数据和状态都是完全独立的,而多线程是共享一块内存空间和一组系统资源(在同一进程内)。线程仍是处理器调度的基本单位,但不再是资源分配单位。
3.线程的状态切换比进程切换的负担要小。
二、如何实现多线程?
线程是指正在执行的一个指令序列。在Java语言中是指从一个线程对象的start()方法执行开始,运行run()方法体中的那一段相对独立的过程。主要有两种实现的方式:
1.继承Thread类
public class ThreadTest extends Thread {
/**
* 覆盖Thread类的run方法
*/
public void run() {
System.out.println("测试线程启动");
}
public static void main(String a[]) {
for (int i = 1; i < 4; i++) {
ThreadTest test = new ThreadTest();//创建线程类ThreadTest对象
test.start();//启动线程
System.out.println("启动线程"+i);
}
}
}
执行结果是:
测试线程启动
启动线程1
启动线程2
测试线程启动
启动线程3
测试线程启动
实现Runnable接口
public class RunnableTest implements Runnable {
/**
* 实现Runnable接口中的run方法
*/
public void run() {
System.out.println("测试线程启动");
}
public static void main(String a[]) {
for (int i = 1; i < 4; i++) {
RunnableTest test = new RunnableTest();//创建线程类RunnableTest的对象
Thread thread = new Thread(test);//创建线程类Thread对象
thread.start();//启动线程
System.out.println("启动线程"+i);
}
}
}
测试结果如下:
测试线程启动
启动线程1
启动线程2
测试线程启动
启动线程3
测试线程启动
三、请用代码说明匿名内部类和TimerTask实现线程的过程
1.匿名内部类实现多线程的demo
public class ThreadTest {
//主函数入口
public static void main(String[] args) {
ThreadTest tt =new ThreadTest();
for(int i=0;i<10;i++){
tt.StartMyThread(i);
}
}
/**
* 这个方法会启动一个匿名线程
* @param threadID
*/
public void StartMyThread(int threadID){
//要传入匿名线程内使用的参数必须定义为final型
final int id = threadID;
//下边是匿名内部类实现多线程的过程
java.lang.Runnable runner = new Runnable(){
public void run(){
int i =10;
boolean flag = true;
while(flag){
try{
Thread.sleep(1000);
//在匿名线程中调用类中的其他方法
otherMethod(id);
if(i>13){
flag = false;
}
}catch(Exception ef){
ef.printStackTrace();
}
}
}
};
//最后,启动这个内部线程
Thread t = new Thread(runner);
t.start();
}
//测试方法
private void otherMethod(int i){
System.out.println("可以直接调用类中的其他方法:"+i);
}
}
测试结果如下://控制台每隔一秒钟输出下边的文字
可以直接调用类中的其他方法:4
可以直接调用类中的其他方法:0
可以直接调用类中的其他方法:9
可以直接调用类中的其他方法:5
可以直接调用类中的其他方法:1
可以直接调用类中的其他方法:6
可以直接调用类中的其他方法:2
可以直接调用类中的其他方法:8
可以直接调用类中的其他方法:7
可以直接调用类中的其他方法:3
2.TimerTask实现线程的demo
使用多线程的还有可能是因为程序中要定时执行某些任务而又不能暂停当前的工作,JDK为这样的功能实现提供了两个类,一个是可作为一个独立线程对象运行的实现了Runnable接口的java.util.TimerTask类;另一个是调度TimerTask对象定时运行的java.util.Timer类。Timer类最常用的一个方法是:
Public void schedule(TimerTask task,long delay,long period)
这个方法会调度task对象在程序启动delay毫秒后,每隔period毫秒执行一次。
import java.util.Timer;
import java.util.TimerTask;
/**
* 使用定时器执行线程
* @author 赵广超
*/
public class TimerPrint extends TimerTask{
private int runCount =0;//运行次数计数器
/**
* @param args
*/
public static void main(String[] args) {
Timer timer = new Timer();//创建一个定时器对象
TimerPrint dw = new TimerPrint();//创建一个定时任务对象
//调度这个定时任务在程序启动五秒后,每隔3秒运行一次
timer.schedule(dw, 5000,3000);//这个方法是Timer中最常用的一个
}
/**
* 重写继承自TimerTask中的run方法,作为线程运行时被调用
*/
public void run(){
runCount++;
System.out.println(runCount +"次定时运行"+System.currentTimeMillis()/1000);
}
}
测试结果如下://控制台每隔三秒输出一行字符串
1次定时运行1353589280
2次定时运行1353589281
3次定时运行1353589282
4次定时运行1353589283
5次定时运行1353589284
6次定时运行1353589285
2012年11月22日写于后湖新村湘艺旅馆