进程是程序的一次执行,是操作系统进行资源分配与调度的基本单位。线程位于进程之中,是进程的实际运行单位。一个进程可并发多个线程,每个线程并行执行不同的任务。
以百度网盘为例,当用户在计算机上打开百度网盘时,操作系统为百度网盘创建一个进程。
- 当用户点击“下载文件”时,进程创建线程,处理用户的下载请求。
- 当用户点击“上传文件”时,同理的,进程创建线程,处理用户的上传请求。
在文件下载期间,若用户点击“文件上传”,此时进程中存在两个并发线程,线程之间并行处理用户的请求。
一、创建并启动线程
方式一:继承Thread类
- 创建一个子类MyThread继承线程类Thread,重写run( )方法
- 创建MyThread线程类的对象
- 调用线程对象的start( )方法启动线程(线程启动后自动执行run( )方法)
/**
* 创建线程类MyThread
*/
public class MyThread extends Thread{
@Override
public void run(){
//描述线程要执行的任务...
}
}
/**
* 启动线程MyThread
*/
public class Test{
public static void main(String[] args){
//创建MyThread线程类对象
MyThread myThread=new MyThread();
//启动线程
myThread.start();
}
}
注意事项:
- 启动子线程调用的是start( )方法,不是run( )方法。
直接调用run( )方法并不会创建新线程,而是将run( )方法当成普通方法执行。
- 在启动子线程的方法中,必须把启动子线程的语句放在主线程的任务后。
若将主线程的任务放在启动子线程之前,也就是先跑完主线程再开启新线程,此时只存在一个线程。
方式二:实现Runnable接口
- 创建一个任务类MyRunnable实现Runnable接口,实现run( )方法。
- 创建MyRunnable任务类的对象。
- 将任务对象交给线程处理,调用start( )方法启动线程。
/**
* 创建任务类MyRunnable
*/
public class MyRunnable implements Runnable{
@Override
public void run(){
//描述任务的执行...
}
}
/**
* 启动线程
*/
public class Test{
public static void main(String[] args){
//创建任务类对象
MyRunnale target=new MyRunnable();
//将任务对象交由线程处理,调用start()方法启动线程
new Thread(target).start();
}
}
匿名内部类写法:
public class Test{
public static void main(String[] args){
//创建Runnable接口的匿名内部类(任务对象)
Runnable target=new Runnable(){
@Override
public void run(){
//描述任务的执行...
}
};
//把任务对象交由线程处理,并调用start()方法启动线程
new Thread(target).start();
}
}
简化形式1:
new Thread(new Runnable(){
@Override
public void run(){
//描述任务的执行...
}
}).start();
简化形式2:
new Thread(()->{
//描述任务的执行...
}).start()
方式三:实现Callable接口
- 创建一个类实现Callable接口,重写call方法
- 把Callable类型的对象封装为FutureTask对象
- 将FutureTask对象交给线程处理,调用start( )方法启动线程
- 获取线程的运行结果
/**
* 创建一个类实现Callable接口
*/
public class MyCallable implements Callable<String>{
@Override
public String call() throws Exception{
//描述任务的执行...
return "hello world";
}
}
/**
* 启动线程
*/
public class Test{
public static void main(String[] args){
//将Callable类型的对象封装成FutureTask
MyCallable<String> myCallable=new MyCallable<>();
FutureTask futureTask=new FutureTask(myCallable);
//将FutureTask对象交由线程处理,调用start()方法启动线程
new Thread(futureTask).start();
//获取线程的运行结果
try{
String result=futureTask.get();
}catch(Exception e){
e.printStackTrace();
}
}
}
二、java.lang.Thread
1、Thread构造器
说明 | |
Thread(String name) | 根据名称创建线程 |
Thread(Runnable target) | 根据任务对象创建线程 |
Thread(Runnable target,String name) | 根据任务对象、名称创建线程 |
2、Thread常用方法
修饰语与返回类型 | 方法名称 | 说明 |
void | start( ) | 启动线程 |
void | run( ) | 定义线程要执行的任务 |
long | getId( ) | 获取线程标识符 |
String | getName( ) | 获取线程名称 |
int | getPriority( ) | 获取线程优先级 |
static Thread | currentThread( ) | 获取当前线程 |
static void | sleep(long time) | 设置线程的休眠时间 |
final void | join( ) | 等待当前线程执行 |