该篇博客目录、
1、线程与进程概述
2、线程的实现(Thread、Runnable)
3、线程的状态
4、线程常用方法
5、线程优先级
6、线程生命周期图
一、线程与进程概述
1、线程:
- 程序中单独顺序的控制流
- 线程本身依靠程序运行
- 线程是程序中的顺序控制流,只能使用分配给程序的资源和环境
- 线程包含单线程、多线程
2、进程
- 执行中的程序
- 一个进程可以包含一个或多个线程(但至少一个)
3、单线程
- 程序中只存在一个线程,实际上主方法就是一个主线程
4、多线程
- 多线程是在一个程序中运行多个任务
- 多线程的目的是更好的使用CPU资源
二、线程的实现(Thread、Runnable)
JAVA中线程的实现有两种方法
- 继承Thread类(需要重写Run()方法)
- 声明实现Runnable接口的类(需要实现Run()方法)
1、继承Thread类
- 需要重写Run()方法
格式
public class 类名 extends Thread{
run(){}
}
例:打印标识是哪个线程在占用CPU资源
继承Thread类__ThreadDemo类
package ThreadDemo;
public class ThreadDemo extends Thread {
private String name;
public ThreadDemo(String name) {
this.name=name;
}
@Override
public void run() {
for(int i=0;i<1000;i++)
{
System.out.println(name+":"+i);
}
super.run();
}
}
测试类Demo
package ThreadDemo;
public class Demo1 {
public static void main(String[] args) {
//创建线程
ThreadDemo t1=new ThreadDemo("A线程");
ThreadDemo t2=new ThreadDemo("B线程");
//启动线程
t1.start();
t2.start();
}
}
可以看出多线程是并发的,AB线程同时交叉占用CPU资源打印出来
2、声明实现Runnable接口的类
需要实现Run()方法
例:打印标识是哪个线程在占用CPU资源
实现Runnable接口的类
package ThreadDemo;
public class Demo1_Runnable implements Runnable {
private String name;
public Demo1_Runnable(String name) {
this.name=name;
}
@Override
public void run() {
for(int i=0;i<1000;i++)
{
System.out.println(name+":"+i);
}
}
}
测试类
package ThreadDemo;
public class Demo1 {
public static void main(String[] args) {
//创建线程
Demo1_Runnable r1=new Demo1_Runnable("A线程");
Demo1_Runnable r2=new Demo1_Runnable("B线程");
//Runnable没有启动方法,所以还是需要Thread来启动
Thread t1=new Thread(r1);
Thread t2=new Thread(r2);
//启动线程
t1.start();
t2.start();
}
}
三、线程的状态
线程的固定操作状态
- 创建状态:准备好了一个多线程的对象
- 就绪状态:调用了start()方法,等待CPU进行调度
- 运行状态:执行Run()方法
- 阻塞状态:暂时停止执行,可能将资源交给其他线程使用
- 终止状态(死亡状态):线程销毁
说明线程也有生老病死的状态
四、线程的常用方法
大多数都在Thread中,所以大部分通过Thread调用
- currentThread():取得当前线程对象
- getName():取得线程名称
- isAlive():判断线程是否启动
- join():线程的强行运行
- sleep():线程的休眠
- yield():线程的礼让
currentThread()、getName()获得当前对象,且获取它的名称Demo
package ThreadDemo;
public class Demo1_Runnable implements Runnable {
private String name;
public Demo1_Runnable(String name) {
this.name=name;
}
@Override
public void run() {
for(int i=0;i<1000;i++)
{
System.out.println(Thread.currentThread().getName());//获得当前对象,且获取它的名称
}
}
}
测试类
package ThreadDemo;
public class Demo1 {
public static void main(String[] args) {
//创建线程
Demo1_Runnable r1=new Demo1_Runnable("A线程");
Demo1_Runnable r2=new Demo1_Runnable("B线程");
//Runnable没有启动方法,所以还是需要Thread来启动
Thread t1=new Thread(r1);
Thread t2=new Thread(r2);
//启动线程
t1.start();
t2.start();
}
}
isAlive()判断线程是否启动Demo
package ThreadDemo;
public class Demo1_Runnable implements Runnable {
private String name;
public Demo1_Runnable(String name) {
this.name=name;
}
@Override
public void run() {
for(int i=0;i<10;i++)
{
System.out.println(name+":"+i);
}
}
}
测试类
package ThreadDemo;
public class Demo1 {
public static void main(String[] args) {
//创建线程
Demo1_Runnable r1=new Demo1_Runnable("A线程");
//Runnable没有启动方法,所以还是需要Thread来启动
Thread t1=new Thread(r1);
//判断线程是否启动
System.out.println(t1.isAlive());
//启动线程
t1.start();
//判断线程是否启动
System.out.println(t1.isAlive());
}
}
join()线程的强行运行Demo
因为程序是先运行主线程的,所以想在某时刻运行自己的线程,即可通过join方法
package ThreadDemo;
public class Demo1_Runnable implements Runnable {
private String name;
public Demo1_Runnable(String name) {
this.name=name;
}
@Override
public void run() {
for(int i=0;i<10;i++)
{
System.out.println(name+":"+i);
}
}
}
测试类
package ThreadDemo;
public class Demo1 {
public static void main(String[] args) {
//创建线程
Demo1_Runnable r1=new Demo1_Runnable("A线程");
//Runnable没有启动方法,所以还是需要Thread来启动
Thread t1=new Thread(r1);
//启动线程
t1.start();
for(int i=0;i<20;i++)
{
if(i>10)//当i大于10之后运行自己的线程
{
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("主线程:"+i);
}
}
}
sleep()线程的休眠Demo(进程执行间隔时间)
package ThreadDemo;
public class Demo1_Runnable implements Runnable {
private String name;
public Demo1_Runnable(String name) {
this.name=name;
}
@Override
public void run() {
for(int i=0;i<10;i++)
{
try {
Thread.sleep(1000);//线程休眠,每次打印间隔时间
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+":"+i);
}
}
}
测试类
package ThreadDemo;
public class Demo1 {
public static void main(String[] args) {
//创建线程
Demo1_Runnable r1=new Demo1_Runnable("A线程");
//Runnable没有启动方法,所以还是需要Thread来启动
Thread t1=new Thread(r1);
//启动线程
t1.start();
}
}
yield()线程的礼让Demo
线程的礼让有时候让,有时候不让,是一个可能性的状态
package ThreadDemo;
public class Demo1_Runnable implements Runnable {
private String name;
public Demo1_Runnable(String name) {
this.name=name;
}
@Override
public void run() {
for(int i=0;i<50;i++)
{
System.out.println(name+":"+i);
if(i==10)
{
System.out.println("礼让");
Thread.yield();//线程的礼让
}
}
}
}
测试类
package ThreadDemo;
public class Demo1 {
public static void main(String[] args) {
//创建线程
Demo1_Runnable r1=new Demo1_Runnable("A线程");
Demo1_Runnable r2=new Demo1_Runnable("B线程");
//Runnable没有启动方法,所以还是需要Thread来启动
Thread t1=new Thread(r1);
Thread t2=new Thread(r2);
//启动线程
t1.start();
t2.start();
}
}
五、线程的优先级
三类优先级
- MIN_PRIORITY
- MAX_PRIORITY
- NORM_PRIORITY
默认是NORM_PRIORITY
Tip:这里优先级设置后,只是提高了该线程先抢到CPU资源的概率,而不是一定能抢到,可以看以下Demo
Demo
package ThreadDemo;
public class ThreadDemo extends Thread {
private String name;
public ThreadDemo(String name) {
this.name=name;
}
@Override
public void run() {
for(int i=0;i<5;i++)
{
System.out.println(name+":"+i);
try {
Thread.sleep(1000);
e.printStackTrace();
};
}
super.run();
}
}
测试类
package ThreadDemo;
public class Demo1 {
public static void main(String[] args) {
//创建线程
ThreadDemo t1=new ThreadDemo("A线程");
ThreadDemo t2=new ThreadDemo("B线程");
ThreadDemo t3=new ThreadDemo("C线程");
t1.setPriority(Thread.MIN_PRIORITY);
t2.setPriority(Thread.MAX_PRIORITY);
t3.setPriority(Thread.NORM_PRIORITY);
//启动线程
t1.start();
t2.start();
t3.start();
}
}
六、线程生命周期图
因为该篇博客只是谈谈基础,所以了解一些就大概即可