多线程学习:线程创建详解

线程创建详解

  线程创建包含线程生命周期中的 新建、就绪、运行 三种状态,相关的api为java.lang.Thread 类
  ① 新建状态:就是刚使用new方法,new出来的线程
如常见的两种方式
  方式一:继承Thread类,并初始化Thread子类

继承Thread的子类 ticketWindow1 = new 继承Thread的子类("一号柜台");

  方式二:实现Runnaable接口

final Runnable接口的类 ticketWindowRunnable = new Runnable接口的类();
Thread thread1 = new Thread(ticketWindowRunnable,"一号窗口");

  两种方式创建时候会调用Thread类的构造方法完成init() 初始化操作(Thread类有多个构造方法,所以初始化类有多种形式)
Thread类构造函数
  ②就绪:就是调用的线程的start()方法后,这时候线程处于等待CPU分配资源阶段,谁先抢的CPU资源,谁开始执行;

 Thread.start();

  源码如下:
start源码
start源码
  此时会调用 private native void start0()方法,Native Method就是一个java调用非java代码的接口。
  start0() 源码如下
start0() 源码
  可以看到start0() 的底层会调用run方法启动线程。完成 ③线程运行

启动模型:
在这里插入图片描述
关于run方法和Start方法
   java里面创建线程之后必须要调用start方法才能真正的创建一个线程,该方法会调用虚拟机启动一个本地线程,本地线程的创建会调用当前系统创建线程的方法进行创建,并且线程被执行的时候会回调 run方法进行业务逻辑的处理
在这里插入图片描述

  • 调用start()时,会创建一个新的子进程并启动
  • 调用run()时,支持thread的普通方法调用,依旧在主线程中调用(比如在main方法中启动,当前线程为main线程)。

两种方式创建线程

 方式一:继承thread类
  1. 写一个类继承Thread 并且重写run方法
public class TicketWindow extends Thread {
    private final String name;
    private static final int MAX = 50;
    private static int index = 1;
    public TicketWindow(String name) {
        this.name = name;
    }
    @Override
    public void run() {
        while (index <= MAX) {
            System.out.println("柜台:" + name + "当前的号码是:" + (index++));
        }
    }
}
  1. 初始化并调用start方法

```java
public class Bank {
    public static void main(String[] args) {
        TicketWindow ticketWindow1 = new TicketWindow("一号柜台");
        ticketWindow1.start();
        TicketWindow ticketWindow2 = new TicketWindow("二号柜台");
        ticketWindow2.start();
        TicketWindow ticketWindow3 = new TicketWindow("三号柜台");
        ticketWindow3.start();
    }
}

注意:
  Java虚拟机会在初始化子类的时候默认初始化子类的父类。
  如果父类的构造方法是带参数的,而且没有无参数的构造方法,那么在子类的构造方法中必须显式地调用父类的构造方法。
  如果父类的构造方法是无参数的,那么在子类中写不写都可以,不写的话会隐式地调用。
  所以初始化子类时候会默认调动父类无参构造方法完成初始化操作。
在这里插入图片描述

 方式二:实现Runnable 接口
  1. 写一个类继承Runable 接口,重写Runable接口
public class TicketWindowRunnable  implements Runnable{
    private int index =0;
    private final static int MAX=50;
    @Override
    public void run() {
        while (index<=MAX){
            System.out.println("当前窗口是"+Thread.currentThread().getName()+"叫到的号码为"+index++);
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

Runable底层只有一个抽象方法 run
在这里插入图片描述

2.通过构造函数,Thread(Runnable target, String name) 初始化Thread对象

final TicketWindowRunnable ticketWindowRunnable = new TicketWindowRunnable();
Thread thread1 = new Thread(ticketWindowRunnable,"一号窗口");

在这里插入图片描述
3. 调用 Thread.start方法启动线程
完整代码:

public class BanKversion2_2 {
    public static void main(String args[]){
        final TicketWindowRunnable ticketWindowRunnable = new TicketWindowRunnable();
        Thread thread1 = new Thread(ticketWindowRunnable,"一号窗口");
        Thread thread2 = new Thread(ticketWindowRunnable,"二号窗口");
        Thread thread3 = new Thread(ticketWindowRunnable,"三号窗口");
        thread1.start();
        thread2.start();
        thread3.start();
    }
}
 thread类与runable接口区别

在这里插入图片描述

runnable优点:

  • runnable实现了资源共享,适合相同程序的多个线程去处理同一资源的情况。
  • 可以避免由于Java的单继承特性带来的局限。
  • 增强了程序的健壮性,代码能够被多个线程共享,代码与数据是独立的。

如果不需要改变线程中除了run方法之外的其他代码,建议使用runnable接口

线程初始化方式

private void init(ThreadGroup g, Runnable target, String name,
                  long stackSize) {
    init(g, target, name, stackSize, null, true);
}

参数含义:线程组,策略接口,线程名,栈大小

  • 线程名 --> 规则:Thread-0++
  • ThreadGroup --> 未传入ThreadGroup 使用父线程
  • Runnable --> 未传入Runable 则不执行
  • stackSize --> 高度依赖平台,有些平台不会有影响

几种初始化方法案例

public class CreateThread {
    public static void main(String args[]){
        Thread t1 = new Thread();
        
        Thread t2 = new Thread(){
            @Override
            public void run(){
                System.out.println("--重写run方法--");
            }
        };

        Thread t3 = new Thread("MyThread");
        
        Thread t4 = new Thread(()->{
            System.out.println(" Runnable ...");
        });

        Thread t5 = new Thread(()->{
            System.out.println("Runable ...");
        },"RunnableThread");

        Thread t6 = new Thread(null, new Runnable() {
            int count=0;
            @Override
            public void run() {
                try {
                    add(1);
                }catch (Error e){
                    System.out.println(count);
                }
            }
            private void add (int i){
                count++;
                add(i+1);
            }
        },"Test",1<<24);

    }
}
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值