java多线程笔记1

核心概念:

(1)进程包含线程

(2)进程是系统资源分配的最小单位;

    线程是系统调度执行的最小单位;

一.创建线程的方法

(1)继承Thread,重写run.通过Thread实例start启动线程;

public class demo1 {
    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();

        while(true) {
            System.out.println("hello main!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

(2)实现Runnable,重写run.通过Thread的实例,把Runnable的实例传进去,再调用start;


class MyRunnable implements Runnable{

    @Override
    public void run() {
        while(true) {
            System.out.println("hello thread!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
public class demo2 {
    public static void main(String[] args) {
        MyRunnable myRunnable = new MyRunnable();
        Thread t = new Thread(myRunnable);
        t.start();

        while(true) {
            System.out.println("hello main!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

(3)通过匿名内部类的方式来编写,本质上是(1);

public class demo3 {
    public static void main(String[] args) {
        Thread t = new Thread() {
            @Override
            public void run() {
                System.out.println("hello thread!");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        t.start();

        while(true) {
            System.out.println("hello main!");
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

(4)通过匿名内部类的方式来编写,本质上是(2);

public class demo4 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(new Runnable() {
            @Override
            public void run() {
                while(true) {
                    System.out.println("hello Thread!");
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        t.start();

        while(true) {
            System.out.println("hello main!");
            Thread.sleep(1000);
        }
    }
}

(5)基于lambda表达式创线程;(推荐)

public class demo5 {
    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while(true) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();
        while(true) {
            System.out.println("hello main");
            Thread.sleep(1000);
        }
    }
}

注意:

(1)代码中创建的new Thread对象的生命周期和内核中实际的线程是不一定一样的,

可能会出现Thread对象存在但是内核中的线程不存在的情况,但是不会存在相反的情况;

(2)start和run的差别:

run:描述了线程要执行的任务,也可以称为线程的入口;

start:调用系统函数,真正在系统内核中,创建线程(创建PCB,加入到链表中),会根据不同的系统调用不同的api,创建好线程之后再来执行run;

(3)不一定非得main线程调用其他线程,其他线程也能调用新线程;

(4)一个Thread对象只能调用一次start;(一个对象只能对应一个线程);

如果Thread对象没有start,此时状态为NEW状态,若start过后则为非NEW状态;

补充概念:

变量捕获:将变量和lambda表达式定义在同一作用域当中,此时lambda内部是可以访问到lambda外部(和lambda同一作用域)的变量的;

Java中变量捕获的特殊要求(C++,JS等语言中没有这种要求):捕获的变量得是final/事实final;

lambda表达式本质上是一个"函数式接口"产生的匿名内部类;

二.前台线程和后台线程

概念

后台线程(deamon守护线程):在线程执行过程中,不能阻止进程结束(即进程结束时,线程也会随之结束);

前台线程:在线程执行过程中,可以阻止进程结束;

注意:

(1)进程(前台线程)要结束,后台线程无力阻止;

(2)后台线程先结束了,也不影响前台线程的结束;

(3)一个进程中,可以有多个前台线程;

多线程的使用场景:

(1)CPU密集型

(2)IO密集型

三.中止线程

(1)通过共享的标记来进⾏沟通

public class demo6 {
    private static boolean isQuit = false;

    public static void main(String[] args) throws InterruptedException {
        Thread t = new Thread(() -> {
            while(!isQuit) {
                System.out.println("hello thread");
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
        t.start();

        Thread.sleep(5000);
        System.out.println(t.isAlive());
        isQuit = true;
        Thread.sleep(1000);
        System.out.println(t.isAlive());
    }
}

(2)调⽤ interrupt() ⽅法来通知

注意:(1)当interrupt()方法被执行时会直接唤醒sleep();

(2)当sleep()被唤醒时,会清空标志位;

(3)因此想要结束循环必须在catch中加上break或者return语句;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值