Java程序设计 多线程【二】

128 阅读3分钟

这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战

Java程序设计 多线程【二】

线程的状态

线程一般具有5种状态,即创建、就绪、运行、阻塞、终止。

image-20220123160601129

创建

在程序中用构造方法创建了一个线程对象后,新的线程对象便处于新建状态。此时,它已经有了相应的内存空间和其他资源,但还处于不可运行状态。

就绪

新建线程对象后,调用该线程的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();
        }
    }
}

image-20220123175016068

输出一次后停一秒再继续下一次

线程中断

在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();
        }
    }
}

image-20220123180756263

实现了线程执行的中断操作,可以发现线程的中断是被动完成的,每当被中断执行后就会产生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);
    }
    }
}

image-20220123190001334

获得主线程

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);
        }
    }
}

image-20220123191328504

线程优先级

image-20220123191414074

方法、常量类型描述
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();
    }
}

image-20220123192250817