线程
首先看看这五个名词的相关概念:
程序:可以实现多个功能的很多代码,是写在硬盘上的.
进程:存在于内存中,有下面的两个特点:
- 是一个实体:有自己的地址空间,如文本区域,数据区域,堆栈区域.
- 是一个运行中的程序,cpu赋予程序生命时,就是一个进程。
线程
多进程:现在的操作系统都是多进程的,可以同时运行多个程序,我们打开任务管理器,切换至进程页面,可以看好多个进程在同时运行.
多线程:一个进程中的多个任务,可以同时进行多个顺序执行流。
好处在于, 提高cpu的资源利用率而且可以共享同一个资源(静态资源,同一个对象实例)
线程状态图
首先列举五种状态:
1.准备状态:创建了这个线程(new Thread()).
2.就绪状态:执行了线程的start()等待CPU分配时间片段.
3.运行状态:获取到了时间片,开始执行任务.
4.阻塞状态:多种因素,比如常用的Scanner类内的方法
而阻塞状态又分为三种
- 等待阻塞:调用wait(),JVM会将此线程放入等待池中
- 同步阻塞:运行中的线程想要获取同步的锁对象(synchronized关键字)时,如果锁对象被其他占用,则JVM将此线程放入锁池中
- 其它阻塞:遇到Thread.sleep()时,或者执行到有阻塞功能的方法(比如Scanner类中常用的方法),或者其他线程在这个线程中调用了join().
5.结束状态:任务执行完毕.
线程的创建
1.继承Thread类,重写run(),方法体定义要执行的逻辑,调用start()开启线程,注意不是调用run().
public class CreateThread extends Thread{//继承Thread类
public void run() {//重写run()
System.out.println("run()运行");
}
public static void main(String[] args) {
Thread t=new CreateThread();//实例化
t.start();//调用start()开启线程
}
}
运行结果
run()运行
2.实现Runnable接口,重写run(),将任务传给Thread对象,由Thread对象调用start().
public class CreateThread implements Runnable{//实现Runnable接口
public void run(){//实现run()
System.out.println("实现Runnable接口的run()");
}
public static void main(String[] args) {
CreateThread c=new CreateThread();//创建对象
Thread t= new Thread(c);//将对象传入Thread对象
t.start();//开启线程
}
}
运行结果
实现Runnable接口的run()
3.使用FutureTask创建对象,再使用Callable创建子类对象,重写call()(相当于run(),该方法带有返回值.),再将Callable对象传给FutureTask,再将FutureTask对象传给Thread对象,调用start() .
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
public class CreateThread {
public static void main(String[] args) {
FutureTask<String> ft=new FutureTask<String>(//创建FutureTask对象
//是利用了匿名内部类的写法.
new Callable<String>() {
public String call() throws Exception {//重写call(),需要处理异常.
int c=0;
for (int i = 1; i < 1001; i++)
c+=i;
System.out.println("1~1000的和值为:"+c);
return c+"";
}
}
);
Thread t = new Thread(ft);//将FutureTask对象传入Thread对象
t.start();//开启线程
}
}
运行结果
1~1000的和值为:500500
可以看到,无论如何创建,最终都要把对象传给Thread对象,由Thread对象调用start()来开启线程.
常用方法
String getName:获取当前线程的名称.
long getId():当前线程的ID.
int getPriority():获取当前线程的优先级.
State getState():获取当前线程的状态.
boolean isAlive():获取当前线程是否在运行.
boolean isDaemon():获取当前进程是否是守护进程(后台进程).
boolean isInterruped():获取当前线程是否被打断.
public class ThreadMethods extends Thread{
public void run() {
int c=0;
for (int i = 1; i < 1001; i++) {
c+=i;
}
System.out.println("1~1000的和为:"+c+".");
}
public static void main(String[] args) {
Thread t=new ThreadMethods();
t.start();
/*String getName() 获取当前线程的名称*/
String threadName=t.getName();
/*long getId() 获取当前线程的ID*/
long id=t.getId();
/*int getPriority() 获取当前线程的优先级*/
int prior=t.getPriority();
/*state getState() 获取当前线程的状态*/
State state= t.getState();
/*boolean isAlive() 获取当前线程是否在运行*/
boolean alive=t.isAlive();
/*boolean isDaemon() 获取当前进程是否是守护进程(即后台线程)*/
boolean daemon=t.isDaemon();
/*boolean isInterrupted() 获取当前线程是否被打断*/
boolean inter=t.isInterrupted();
System.out.println("线程的名称:"+threadName);
System.out.println("线程的ID:"+id);
System.out.println("线程的优先级:"+prior);
System.out.println("线程的状态:"+state);
System.out.println("线程是否在运行:"+alive);
System.out.println("线程是否是守护进程"+daemon);
System.out.println("线程是否被打断:"+inter);
}
}
运行结果
线程的名称:Thread-0
线程的ID:11
线程的优先级:5
线程的状态:RUNNABLE
线程是否在运行:true
线程是否是守护进程false
线程是否被打断:false
1~1000的和为:500500.