Java多线程

九. 多线程

  • 进程和线程

    进程是一个应用程序(一个进程是一个软件)

    线程是一个进程中的执行场景/执行单元(一个进程可以启动多个线程)

    例如:在命令行输入java HelloWorld后,会启动JVM(进程),JVM启动一个主线程调用main方法,同时再启动一个垃圾回收线程负责看护、回收垃圾。此时java程序中至少有两个线程并发

  • 两个进程的内存相互独立,不共享

    两个线程堆内存和方法区内存共享,栈内存独立(一个线程一个栈)

  • 多线程并发:n个线程有n个栈空间,栈之间相互独立

    java中的多线程机制可以提高程序的处理效率

  • 使用多线程机制后,main方法结束程序不一定结束(main方法结束只是主线程结束、主栈空了,其他栈/线程可能还在压栈/弹栈)

  • 对于多核CPU,可以实现真正的多线程并发(n个核可以有n个线程同时并发执行)

    对于单核CPU,不能做到真正的多线程并发,但可以在多个线程间频繁切换执行

  • 以下程序除垃圾回收线程外只有一个线程(程序只有一个栈)

public class ThreadTest01 {
    public static void main(String[] args) {
        m1();
    }
    private static void m1() {
        m2();
    }
    private static void m2() {
    }
}
  • java中实现线程:编写一个类,继承java.lang.Thread类,重写run方法

    start()方法:启动分支线程,在JVM中开辟新的栈空间(一旦开辟成功,start()方法结束,线程启动成功)

    启动成功的线程会自动调用run方法,且run方法在分支栈的栈底(main方法在主栈的栈底,run和main是平级的)

public class ThreadTest02 {
    public static void main(String[] args) {
        MyThread mt = new MyThread();
        mt.start();		//启动线程,结果是主线程和分支线程交替输出
        //mt.run();		不启动线程,按自上而下的顺序运行,先输出分支线程,再输出主线程
        for (int i = 0; i < 10; i++) {
            System.out.println("主线程:" + i);
        }
    }
}
class MyThread extends Thread {		//定义线程类
    public void run() {
        for (int i = 0; i < 10; i++) {
            System.out.println("分支线程:" + i);
        }
    }
}
  • 第二种方法:实现java.lang.Runnable接口,重写run方法

    这种方式更常用,可以继承其他的类

public class ThreadTest03 {
    public static void main(String[] args) {
        Thread t = new Thread(new MyRunnable());		//Thread构造方法
        t.start();
    }
}
class MyRunnable implements Runnable {		//定义一个可运行的类
    public void run() {
    }
}
//采用匿名内部类方式:
Thread t = new Thread(new Runnable() {
	public void run() {}
});
t.start();

线程生命周期

  1. 新建状态:刚new出来的线程对象
  2. 就绪状态:新建状态调用start方法进入就绪状态。就绪状态又叫做可运行状态,表示当前线程具有抢夺CPU时间片的权利(CPU时间片就是执行权)
  3. 运行状态:抢夺到CPU时间片的线程执行run方法,run方法的开始执行标志着线程进入运行状态。当CPU时间片用完之后会重新回到就绪状态继续抢夺CPU时间片,再次抢到CPU时间片后会重新进入run方法继续执行
  4. 阻塞状态:处于运行状态的线程遇到阻塞事件(例如接收用户键盘输入、sleep方法等),进入阻塞状态,阻塞状态的线程会放弃之前占有的CPU时间片,需要回到就绪状态抢夺CPU时间片
  5. 死亡状态:run方法执行结束

在这里插入图片描述

  • 关于线程名(默认线程名为Thread-0、Thread-1……)

    static Thread currentThread()方法:获取当前线程对象

public class ThreadTest04 {
    public static void main(String[] args) {
        MyThread2 t = new MyThread2();
        t.start();
        System.out.println(t.getName());		//获取线程名字,输出Thread-0
        t.setName("heisenberg");		//设置线程名字
        System.out.println(t.getName());		//输出heisenberg
        Thread currentThread = Thread.currentThread();
        //main方法中当前线程就是主线程
        System.out.println(currentThread.getName());		//输出main
    }
}
class MyThread2 extends Thread{
	Thread currentThread = Thread.currentThread();
	//t执行run方法,当前线程就是t
	System.out.println(currentThread.getName());		//输出heisenberg
	public void run() {}
}
  • static void sleep(long millis)方法:让当前线程进入休眠(进入“阻塞状态”),放弃占有CPU时间片,给其他线程使用
<
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值