day01-javaee-多线程

1、什么是线程

线程的实现方式有很多种:
1) 内核线程=>Java中的线程,是基于内核线程的轻量级实现(轻量级进程:相比进程,创建、调度、销毁效率要高很多)
2) 用户线程:有程序自己来实现线程,包括线程的调度等等
安卓以前的开发语言是Java,最新的是kotlin(运行在jvm上的),里 面使用的就是协议(用户线程)

2、进程与线程

1、多个进程的内存是隔开的,一个进程中多个线程,可以共享内存(进程包含线程)
2、进程是系统分配的最小单位,线程是系统调度cpu执行的最小单位
3、进程的创建、销毁代价比进程小(状态转换进程的开销大与线程)
4、线程(有bug)可能会造成整个进程挂掉,进程间是独立运行的(可能存在进程通信)

3、多线程的优势/使用场景

1、充分利用cpu资源,提高执行效率
2、io等阻塞时(如果希望能同时接收输入)

4、缺陷/注意事项:

1、线程的创建/销毁也是具有一定的系统开销:所以一般用于执行耗时时间比较长的任务
2、增加编码的复杂程度:和se代码执行顺序不一样的地方,后面会学习的线程安全问题

5、线程状态和状态转移的意义

在这里插入图片描述
(1) new:创建态
(2) runnable:可运行态
程序无法判定某个时间到底是就绪态还是可运行态,所以这两个状态对于程 序来说没有意义
(3) 等待
(4) 超时等待
(5) 阻塞
(6) 销毁

6、Thread线程

Java中,创建线程,就是new一个Thread

常见的构造方法
在这里插入图片描述

7、创建线程的方式

1、 继承Thread
【继承Thread => 重写run方法(定义要执行的任务代码)】

public class ThreadDemo01 {

    public static void main(String[] args) {
        //继承Thread
        //创建MyThread实例
        MyThread myThread = new MyThread();
        //运行一个线程,申请系统调度运行
        myThread.start();

        //继承的写法2:使用一个匿名内部类
        Thread t = new Thread(){//属于继承Thread但没有名称的子类
            @Override
            public void run() {
                System.out.println("匿名内部类run");
            }
        };
        t.start();

    }

    //继承的方式 1、继承Thread  2、重写run方法(定义要执行的任务代码)
    private static class MyThread extends Thread{
        @Override
        public void run() {
            System.out.println("MyThread.run");
        }
    }
}

2、 实现Runnable接口
【实现Runnable接口 =》重写Runnable的run方法 =》】

//实现Runnable
public class RealizeRunnable {

    public static void main(String[] args) {
        //实现Runnable写法1
        Thread t1 = new Thread(new MyRunnable());
        t1.start();

        //实现Runnable写法2:匿名内部类
        Runnable r2 = new Runnable() {//属于Runnable实现类,只是没有名字
            @Override
            public void run() {
                System.out.println("匿名内部类1 run");
            }
        };
        Thread t2 = new Thread(r2);
        t2.start();

        //也可以把匿名内部类的对象直接写在构造方法的参数上(!!!常用)
        Thread t3 = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("匿名内部类2 run");
            }
        });
        t3.start();

        //了解:lambda表达式
        Thread t4 = new Thread(() -> System.out.println("匿名内部类2 run"));
        t4.start();

    }

     public static class MyRunnable implements Runnable{

         @Override
         public void run() {
             System.out.println("MyRunnable run");
         }
     }
}


3、实现Callable接口

8、线程的启动

thread.start()=》 申请系统调度,执行thread中的任务(重写的run方法)

main方法执行,也是存在一个main线程的
在这里插入图片描述
Thread中,start()和run()的区别
1) start:启动线程的方式
2) run:属于线程任务的描述

public class StartVsRun {

    //main方法执行:

    /**
     * java StartVsRun:
     *     1、执行java.exe进程,分配内存
     *     2、创建java虚拟机,执行StartVsRun类加载
     *     3、创建一个main线程,执行StartVsRun.main()
     * @param args
     */
    public static void main(String[] args) {
        //while(true){}

        //t线程,一直处于运行()
        //main线程,只是执行了new Thread(new Runnable()):只是执行这两个构造方法
        /*Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){}
            }
        },"t线程" );
        t.start();*/

        //线程对象.run,只是属于普通对象的实例方法调用,没有启动线程!
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){}
            }
        },"t线程" );
        t.run();
    }
}

在这里插入图片描述

9、Thread常见的属性

在这里插入图片描述

//获取线程属性
public class getThreadShuxing {

    public static void main(String[] args) {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true){}
            }
        });
        //后台线程:java进程,至少有一个非后台线程(用户线程)存活,进程才不会退出
        //如果把t线程在启动前设置为后台进程,进程就不会管t线程是否执行完
        //t.setDaemon(true);
        t.start();
        System.out.println("ID:     "+t.getId());//ID 是线程的唯一标识,不同线程不会重复
        System.out.println("名称:   "+t.getName());//获取线程名称
        System.out.println("状态:   "+t.getState());//获取线程状态
        System.out.println("优先级: "+t.getPriority());//实质写代码没用
        System.out.println("后台进程:"+t.isDaemon());//是否是后台线程
        System.out.println("是否存活:"+t.isAlive());//是否存活:如果启动后销毁前,都是存活

    }
}

10、Thread中的常用方法

当前线程(t.join在哪个线程执行,就是谁)等待,直到线程引用执行完毕

在这里插入图片描述
当前线程等待,最多给定的毫秒数,或者线程引用对象死亡
t.join(3000);

在这里插入图片描述

//常用api
public class ThreadJoin {

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("t线程 run");
                //注释掉,就是先打印t线程,在打印main
                //t.join不注释:t线程一直运行态,main等待状态
                //t.join(3000)不注释:t线程先打印,然后一直运行;main线程等3s后打印,然后结束
                while (true){}
            }
        },"t线程");
        t.start();

        /**
         * Waits for this thread to die.
         * 等待,直到这个线程死亡
         * 考虑:谁等待:main?谁死亡:t线程?
         * 当前线程(t.join在哪个线程执行,就是谁)等待,直到线程引用执行完毕
         *
         */
        //t.join();

        /**
         * Waits at most millis milliseconds for this thread to die.
         *当前线程等待,最多等待给定的毫秒数,或者线程引用对象死亡
         */
        t.join(3000);
        System.out.println("t线程 start,这里是main");

    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值