当前位置: 首页 > article >正文

多线程(3)线程中的常用结构

1、构造器

  • public Thread() :分配一个新的线程对象
  • public Thread(String name) :分配一个指定名字的新的线程对象。
  • public Thread(Runnable target) :指定创建线程的目标对象,它实现了Runnable接口中的run方法
  • public Thread(Runnable target,String name) :分配一个带有指定目标新的线程对象并指定名字。
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("a try");
    }//传入匿名对象并重写run方法
},"Thread Three").start();

关于Runnable target 的传参:(1)可以传入匿名对象,例如new Runnable()

(2)可以传入 一个实现了Runnable接口的(重写了run方法)实现类的实例对象

2、介绍方法

start():启动线程,调用线程的run()

run():将线程中需要执行的操作写入,无论是继承Thread类还是实现Runnable接口都需要重写

currentThread():获取当前执行代码对应的线程

getName():获取线程名

setName():设置线程名

sleep(long millis):静态方法,调用时可以使当前线程睡眠制定的秒数,使用时必须捕获异常,可能因为被打断而抛出的异常名为:InterruptedException。

yield():静态方法,一旦执行就释放释放CPU的执行权(可能执行另一线程)

join():在线程A中通过线程B调用join(),意味着线程A进入阻塞状态,直到线程B执行完毕,线程A才恢复运行。

isAlive():线程是否存活,返回值类型true 或者 false

public class EvenNumber {
    public static void main(String[] args) {
        Print p = new Print("Thread one");//给线程命名
        p.setName("Thread Two");
        p.start();

        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("a try");
            }
        },"Thread Three").start();//此处使用包含Runnable target参数和String name参数的构造器。

        try {
            Print.sleep(3);//静态方法,通过子类调用
            //Thread.sleep(3);也可以直接通过Thread父类调用。
        }catch (Exception e){
            e.getMessage();
        }//此处调用try-catch处理编译时异常,不能采用throws的原因是Print继承于Tread父类,父类中没有写throws方法子类中也不能使用。
        Print.yield();//静态方法,原理同上。

        for (int i = 0; i <=100; i++) {
            if(i%2==0)
                System.out.println(Thread.currentThread().getName()+":"+i);

            if (i==20){
                try {
                    p.join();//满足if条件时,main线程阻塞,直到Thread Two结束线程
                }catch (Exception e){
                    e.getMessage();
                }
            }

            while (i==90){
                System.out.println(p.isAlive());
                break;
            }
        }


    }
}

class Print extends Thread{
    public Print() {
    }

    public Print(String name) {
        super(name);
    }

    public Print(Runnable target, String name) {
        super(target, name);
    }

    @Override
    public void run() {
        for (int i = 0; i <=100; i++) {
            if(i%2==0)
                System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

过时的方法:

stop():强行结束线程的执行

void suspend():暂停线程

void resume():恢复线程,二者必须成对使用,否则可能造成死锁,不建议使用

线程的优先级:

getPriority():获取线程的优先级(默认5)

setPriority();设置线程的优先级(1-10)

优先级高 的线程被CPU分配执行的概率大一些,这一点在单核CPU中更为明显。

MAX_PRIORITY(10):最高优先级

MIN_PRIORITY(1):最低优先级

NORM_PRIORITY(5):普通优先级

3、线程的生命周期

最初的(JDK1.5)的分类:出生、就绪、运行、死亡、阻塞

JDK1.5之后:

6种状态:NEW  RUNNABLE  BLOCKED  WAITING  TIME_WAITING  TERMINATED

三种阻塞的具体分类:

锁阻塞(BLOCK):等待一个监视器锁<-- -Lock  synchronlzed

获得监视器锁对象之后回到Runnable状态。

计时等待(TIME_WATING):Thread类的sleepjoinObject类的wait,LockSupport类的park方法,并且在调用这些方法时,设置了时间 

具体方法介绍;Tread sleep、带有超时值的Object的wait、带有超时值的Tread 的jion、lockSupport.parkNanos、LockSupport.parkUntil

直到时间到或interrup打断等待才重新回到Runnable之中。

-

无限等待(WAITING):一个正在无限期等待另一个线程执行一个特别的(唤醒)动作的线程

具体方法以及对应的解决方案:

        • 通过Object类的wait进入WAITING状态的要有Object的notify/notifyAll唤醒;
        • 通过Condition的await进入WAITING状态的要有Condition的signal方法唤醒;
        • 通过LockSupport类的park方法进入WAITING状态的要有LockSupport类的unpark方法唤醒
        • 通过Thread类的join进入WAITING状态,只有调用join方法的线程对象结束才能让当前线程恢复;

说明:当从WAITING或TIMED_WAITING恢复到Runnable状态时,如果发现当前线程没有得到监视器锁,那么会立刻转入BLOCKED状态。

课件内容补充:

守护线程的特点:在后台运行,作用是为其他线程提供服务。如果所有的非守护线程都死亡,那么守护线程自动死亡。

JVM的垃圾回收线程就是典型的守护线程。

调用setDaemon(true)方法可将指定线程设置为守护线程。必须在线程启动之前(调用start方法之前)设置,否则会报IllegalThreadStateException异常。

public class ProtectTest {
    public static void main(String[] args) {
        Protector p = new Protector();
        p.setDaemon(true);//在start之前设置守护线程
        p.start();
        for(int i =0;i<10;i++){
            System.out.println(i);
        }
    }
}
class Protector extends Thread{
    @Override
    public void run() {
        while (true){
            System.out.println("I'm protecting you.");
            try {
                Thread.sleep(1);
            }catch (Exception e){
                e.getMessage();
            }
        }
    }
}


http://www.kler.cn/a/417513.html

相关文章:

  • 【玩转全栈】--创建一个自己的vue项目
  • Python爬虫-如何正确解决起点中文网的无限debugger
  • 【高阶数据结构(一)】:LRU Cache
  • (dpdk f-stack)-堆栈溢出-野指针-内存泄露(问题定位)
  • 2025年2月4日--2月9日(ue4.0shader抄写+ue5肉鸽独立游戏视频)
  • 企业高效管理策略中的关键一环:WorkWin 监控上网时间的软件的效能剖析
  • 如何实现字符串反转-多语言
  • CSS笔记(二)类名复用
  • SpringBoot开发——结合Nginx实现负载均衡
  • mac下安装Ollama + Open WebUI + Llama3.1
  • [高等数学]一元积分学的应用
  • (SAST检测规则-3)固定的 SessionID 缺陷详解
  • unreal engine5中多个摄像机切换
  • Hbase 部署
  • Spring项目中RabbitMq的使用(工作队列模式)
  • 2024.11.29(单链表)
  • International Journal of Medical Informatics投稿经历时间节点
  • Java基础——(三)对象和类
  • Python入门(19)--最终篇
  • Mybatis Plus 增删改查方法(一、增)
  • 09.ES13 10.ES14
  • [ACTF2020 新生赛]BackupFile--详细解析
  • eltable el-table 横向 滚动条常显
  • 05《存储器层次结构与接口》计算机组成与体系结构 系列课
  • STM32的一些知识技巧
  • 关于edu的信息收集的一次笔记分享