这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战
Java程序设计 多线程【二】
线程的状态
线程一般具有5种状态,即创建、就绪、运行、阻塞、终止。
创建
在程序中用构造方法创建了一个线程对象后,新的线程对象便处于新建状态。此时,它已经有了相应的内存空间和其他资源,但还处于不可运行状态。
就绪
新建线程对象后,调用该线程的start()方法就可以启动线程。当线程启动时,线程进入就绪状态。
运行
当就绪状态的线程被调用并获得处理器资源时,线程就进入了运行状态。
堵塞
一个正在执行的线程在某些特殊情况下,如果被人为挂起或需要执行耗时的输入输出操作时,会让出CPU并暂时中止自己的执行,进入堵塞状态。
死亡
线程调用stop()方法时或run()方法执行结束后,即处于死亡状态。处于死亡状态的线程不具有继续运行的能力。
线程操作的相关方法
线程的命名和取得
| 方法 | 类型 | 描述 |
|---|---|---|
| public Thread(Runnable target,String name) | 构造 | 实例化线程对象,接收Runnable接口子类对象,同时设置线程名称 |
| public final void setName(String name) | 普通 | 设置线程名称 |
| public final String getName() | 普通 | 取得线程名称 |
取得当前线程对象:public static Thread currentThread()
package org.test;
class Test implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName());
}
}
public class Hello {
public static void main(String[] args) throws Exception{
Test a = new Test();
new Thread(a,"A").start();
new Thread(a,"B").start();
new Thread(a).start();
}
}
如果没有设置线程名称,系统会自动为其分配一个名称,名称的形式以“Thread-xxx”的方式出现
线程休眠
| 方法 | 类型 | 描述 |
|---|---|---|
| public static void sleep(long millis)throws InterruptedException | 普通 | 设置线程休眠的毫秒数,时间一到自动唤醒 |
| public static void sleep(long millis,int nanos) throws InterruptedException | 普通 | 设置线程休眠的毫秒数与纳秒数,时间一到自动唤醒 |
在进行休眠的时候有可能会产生中断异常InterruptedException,中断异常属于Exception的子类,程序中必须强制性进行该异常的捕获与处理。
package org.test;
public class Hello {
public static void main(String[] args) throws Exception{
Runnable run=() ->{
for (int i=0;i<=5;i++){
System.out.println(Thread.currentThread().getName()+" "+i);
try{
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
};
for(int x=0;x<=5;x++){
new Thread(run,""+x).start();
}
}
}
输出一次后停一秒再继续下一次
线程中断
在Thread类提供的线程操作方法中很多都会抛出InterruptedException中断异常,所以线程在执行过程中也可以被另外一个线程中断执行
| 方法 | 类型 | 描述 |
|---|---|---|
| public boolean isInterrupted() | 普通 | 判断线程是否被中断 |
| public void interrupt() | 普通 | 中断线程执行 |
package org.test;
public class Hello {
public static void main(String[] args) throws Exception{
Thread thread = new Thread(()->{
System.out.println("休眠5秒");
try{
Thread.sleep(5000);
}catch (InterruptedException e){
System.out.println("出现异常");
}
});
thread.start();
Thread.sleep(1000);
if(!thread.isInterrupted()){
System.out.println("中断");
thread.interrupt();
}
}
}
实现了线程执行的中断操作,可以发现线程的中断是被动完成的,每当被中断执行后就会产生InterruptedException异常。
线程强制执行
某个线程对象需要优先执行完成,则可以设置为强制执行,待其执行完毕后其他线程再继续执行
线程强制执行:
public final void join() throwsInterruptedException
package org.test;
public class Hello {
public static void main(String[] args) throws Exception{
Thread mainThread = Thread.currentThread();
Thread thread = new Thread(()->{
for(int i=0;i<10;i++){
if(i==2){
try{
mainThread.join();
}catch (InterruptedException e){
e.printStackTrace();
}
}
try{
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+""+i);
}
},"a");
thread.start();
for(int x=0;x<10;x++){
Thread.sleep(100);
System.out.println(x);
}
}
}
获得主线程
Thread mainThread = Thread.currentThread();
设置强制执行条件和任务
if(i==2){
try{
mainThread.join();
}catch (InterruptedException e){
e.printStackTrace();
}
}
主线程
for(int x=0;x<10;x++){
Thread.sleep(100);
System.out.println(x);
}
线程礼让
当满足某些条件时,可以将当前的调度让给其他线程执行,自己再等待下次调度再执行
线程礼让:public static void yield()
package org.test;
public class Hello {
public static void main(String[] args) throws Exception{
Thread thread = new Thread(()->{
for(int i=0;i<10;i++){
if(i%2==0){
Thread.yield();
System.out.println(Thread.currentThread().getName()+"礼让");
}
try {
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+""+i);
}
},"a");
thread.start();
for(int i=0;i<10;i++){
Thread.sleep(100);
System.out.println(i);
}
}
}
线程优先级
| 方法、常量 | 类型 | 描述 |
|---|---|---|
| public static final int MAX_PRIORITY | 常量 | 最高优先级,数值为10 |
| public static final int NORM_PRIORITY | 常量 | 中等优先级,数组为5 |
| public static final int MIN_PRIORITY | 常量 | 最低优先级,数值为1 |
| public final void setPriority(int newPriority) | 普通 | 设置线程优先级 |
| public final int getPriority() | 普通 | 取得线程优先级 |
package org.test;
public class Hello {
public static void main(String[] args) throws Exception{
Runnable run=()->{
for(int i=0;i<10;i++){
try{
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"执行");
}
};
Thread a=new Thread(run,"a");
Thread b=new Thread(run,"b");
Thread c=new Thread(run,"c");
a.setPriority(Thread.MAX_PRIORITY);
b.setPriority(Thread.MIN_PRIORITY);
c.setPriority(Thread.NORM_PRIORITY);
a.start();
b.start();
c.start();
}
}