多线程基础部分Part 1

目录

进程和线程

进程:程序在系统中的一次执行过程

线程:进程中的一个子任务

进程和线程的区别

描述线程对象的类-Thread类

run方法和start方法的区别

run方法

start方法

创建线程:Java中创建一个线程一共有四种方式

a.继承Thread类,覆写run方法(现成的核心工作任务方法)

a方式下的线程与启动

使用匿名内部类创建Tread对象写法

b.覆写Runnable接口,覆写run方法

b方式下的线程与启动

使用匿名内部类实现Runnable接口

使用Lambda表达式

c.覆写Callable接口,覆写call方法

d.使用线程池创建线程

Thread类常见方法

1.构造方法

2.Thread类的核心属性

3.启动线程调用的是Tread类的start方法

4.中断线程

 中断线程的两种方式

 线程收到内置的中断通知的两种方式

5.等待另一个线程-join方法

6.获取当前正在执行的线程对象

7.休眠当前进程

8.将线程状态从运行态转换为就绪态 =>yield()方法

线程的状态

NEW

RUNNABLE

BLOCKED , WAITING  ,  TIMED_WAITING

TIMED_WAITING

BLOCKED

 WAITING

TERMINATED


进程和线程

进程:程序在系统中的一次执行过程

进程是现在操作系统中资源分配(CPU,内存等关键系统信息)的最小单位,不同进程之间是相互独立的。

任务管理器中的进程就是这个

线程:进程中的一个子任务

线程是进程中的一个独立任务,比如浏览器进程的下载,听音乐等,就是浏览器进程的一些线程

同一个进程的所有线程共享该进程资源,线程是操作系统任务执行(系统调度)的基本单位

进程和线程的区别

1.进程是os资源分配的基本单位,线程是os系统调度的基本单位。

2.创建和销毁进程的开销要比线程大得多(开销相当于时间),线程更加轻量化。

3.调度一个线程也比调度一个进程快得多。(启动浏览器/浏览器标签,肯定是标签快)

4.进程包含线程,每一个进程至少包含一个线程(主线程)。

5.进程之间彼此相对独立,不同的进程不会共享内存空间,同一个进程的线程共享内存空间。


描述线程对象的类-Thread类

我们程序的入口是main方法,所有的调用都是从主方法开始的,所以相同的,所有的线程任务也是从主方法(主线程)开始进行。

Java中描述线程的类是Thread类——java.lang.Thread类线程的核心类,都是通过Thread类来启动一个线程。

当我们覆写完线程子类的run方法,在主方法中调用 线程对象.start方法来启动线程。

所有线程之间是并行关系,同时在电脑中执行

使用jconsole可以观察线程状态,用于对比各线程

run方法和start方法的区别

run方法

run方法是线程类的工作任务,也就是说,run方法决定了线程启动后要干什么,当run方法执行完毕(JVM启动run方法),线程会进入销毁状态。

start方法

start方法是Thread类中启动线程的方法,只有线程对象调用start方法时才会被系统调度,进入运行状态。

创建线程:Java中创建一个线程一共有四种方式

a.继承Thread类,覆写run方法(现成的核心工作任务方法)

//继承Thread类
    public static class Run2 extends Thread{
        @Override
        public void run() {
            System.out.println("继承Thread类");
        }
    }

ps:通过Thread类的start启动线程

a方式下的线程与启动

1.一个子类继承Thread类

2.覆写run方法

3.产生当前这个子类对象,而后调用start方法启动线程

使用匿名内部类创建Tread对象写法

//继承内部类创建Thread对象
        Thread thread3 = new Thread() {
            @Override
            public void run() {
                System.out.println("继承匿名内部类的Thread对象");
            }
        };

b.覆写Runnable接口,覆写run方法

 public static class Run implements Runnable{
        @Override
        public void run() {
            System.out.println("实现Runnable接口");
        }
    }

ps:通过Thread类的start启动线程

b方式下的线程与启动

1.实现Runnable接口

2.覆写run方法

3.创建Thread类的对象,调用start方法

使用匿名内部类实现Runnable接口

//继承匿名内部类的Runnable
        Thread thread2 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("继承匿名内部类的Runnable");
            }
        },"小鹏");

使用Lambda表达式

Thread thread3 = new Thread(()-> {
        System.out.println("Lambda表达式的线程创建");
    },"阿铭");

c.覆写Callable接口,覆写call方法

d.使用线程池创建线程

Thread类常见方法

Thread类就是JVM描述管理线程的类,每个线程都对应唯一的Thread对象

1.构造方法

如,传入Runnable接口类的方法都是构造方法

ps:可以在传入接口后给线程命名

2.Thread类的核心属性

一图流

3.启动线程调用的是Tread类的start方法

4.中断线程

 中断线程的两种方式

a.通过共享变量进行中断

b.通过Thread.interrupted()静态方法或者Thread对象的成员方法isInterrupted()

Thread类中存在一个线程是否中断的属性

 线程收到内置的中断通知的两种方式

a.当线程调用sleep/wait/join等方法处在阻塞状态时,收到中断通知thread.interrupt()

抛出中断异常 InterruptedException

当抛出异常后,当前线程的中断状态就会清除

b.线程没有调用以上三种方法,处在正常运行状态时收到中断通知thread.interrupt()

Thread.interrupted()判断当前线程是否被中断,若中断状态为true 清楚中断标志

 Thread.currentThread.isInterrupted(); 判断指定线程对象是否状态为中断状态,若状态为true,不会清除中断标志

5.等待另一个线程-join方法

采用join方法,当一个线程中调用了另一个线程的join方法,那么要等调用线程执行完毕,才能继续执行此线程的后续代码。

 join方法的变种

6.获取当前正在执行的线程对象

Thread.currentThread() => 获取正在执行的线程对象

例如

Thread.currentThread().getName()
Thread.currentThread().isInterrupted()

7.休眠当前进程

Thread.sleep(long millis) (ms)方法,在哪个线程中使用就休眠哪个进程。

8.将线程状态从运行态转换为就绪态 =>yield()方法

调用yield方法的线程会主动让出CPU资源,从运行态转为就绪态,等待被CPU继续调度。

到底啥时候让出CPU,又是啥时候被CPU再次调度,都是os调度的,我们无权选择。

此方法有两种可能性:

a.线程让出运行态之后,马上又调度

 

b.线程让出运行态之后,很久都不调度

此方法完全由CPU控制,我们不可控,所以使用不多。

线程的状态

附上一张状态图,下文叙述会依托下面此图

NEW

新建线程对象,new一个Thread对象就是new状态

新建状态,还没开始执行

RUNNABLE

就绪和运行,线程对象.start就是RUNNABLE状态

下一个状态,可执行状态(真正在运行和即将开始执行,都是这个状态)

 

BLOCKED , WAITING  ,  TIMED_WAITING

等待状态,三种等待状态均为阻塞状态(该线程需要暂缓执行,这三个造成的暂缓执行原因不同)

TIMED_WAITING

 

超时等待,表示该线程需要等待一段时间后再恢复执行

例如sleep方法就是此种等待方式

 

BLOCKED

当线程被锁住等待获取锁对象就是BLOCKER状态

 WAITING

当线程使用lock.wait()方法时,说明进入线程等待状态,需要另一个线程的lock.notify方法解锁此线程

 

TERMINATED

run方法执行完毕,或者抛出异常不正常执行完毕

终止状态,表示当前线程已经执行结束了,可以销毁了

可以用主线程的线程对象.isAlive()方法判断线程是否存活

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值