• Java中的线程


    线程

    什么是线程:

    image-20221117184424814

    image-20221117184429961

    什么是多线程

    image-20221117184455661

    学习目的:

    image-20221117184751362

    多线程的创建

    方式一:继承Thread类

    image-20221117185309899

    public class MyThread{
        public static void main(String[] args) {
            Thread thread01 = new Thread01();
            thread01.start();
            for (int i = 0; i < 5; i++) {
                System.out.println("主线程执行输出:"+i);
            }
        }
    }
    
    class Thread01 extends Thread{
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println("子线程执行输出:"+i);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    image-20221117185920965

    image-20221117190049789

    注意:

    如果用thread01.run()而不用thread01.start(),那么将还是单线程执行。

    主线程任务不要放在子线程之前,否则还是单线程的情形。

    方式二:实现Runnable

    方式二相对于方式一来说线程类可以继承别的类。

    image-20221117190714908

    public class MyThread{
        public static void main(String[] args) {
            Runnable r = new MyRunnable();
            // r为任务对象,要交给一个线程对象去处理。
            Thread thread = new Thread(r);
            thread.start();
            for (int i = 0; i < 5; i++) {
                System.out.println("主线程输出:"+i);
            }
        }
    }
    
    class MyRunnable implements Runnable{
    
        @Override
        public void run() {
            for (int i = 0; i < 5; i++) {
                System.out.println("子线程输出:"+i);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    image-20221117191621000

    image-20221117191835605

    public class MyThread{
        public static void main(String[] args) {
            Runnable r = new Runnable() {
                @Override
                public void run() {
                    for (int i = 0; i < 5; i++) {
                        System.out.println("子线程输出:"+i);
                    }
                }
            };
            // r为任务对象,要交给一个线程对象去处理。
            Thread thread = new Thread(r);
            thread.start();
            for (int i = 0; i < 5; i++) {
                System.out.println("主线程输出:"+i);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    方式三:jdk5.0新增,实现Callable接口

    image-20221117194327720

    image-20221117194636585

    public class ThreadDemo {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            // 创建callable任务对象
            Callable<String> c = new MyCallable(100);
            // 把callable任务对象交给FutureTask对象:是Runnable对象(实现了Runnable接口),可以交给Thread
            // FutureTask对象可以使用get方法得到线程返回的结果
            FutureTask<String> f = new FutureTask<>(c);
            Thread t = new Thread();
            t.start();
            // 如果f任务没有执行完毕,则f.get()会等待,线程跑完才提取结果
            System.out.println(f.get());
        }
    }
    class MyCallable implements Callable<String>{
        private int n;
    
        public MyCallable(int n) {
            this.n = n;
        }
    
        @Override
        public String call() throws Exception {
            int sum = 0;
            for (int i = 1; i <= n; i++) {
                sum = sum + i;
            }
            return "子线程的结果为:"+sum;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    image-20221117210743828

    image-20221117210820249

    三种方式的对比

    image-20221117210847107

    Thread的常用方法

    自定义线程名字1:

    public class ThreadDemo {
        public static void main(String[] args) {
            Thread t1 = new MyThread();
            t1.setName("1号");
            t1.start();
    
            Thread t2 = new MyThread();
            t2.setName("2号");
            t2.start();
    
            // 哪个线程执行它,他就返回哪个线程(当前线程对象)。
            Thread ct = Thread.currentThread();
            // 主线程调用它,拿到主线程的名字(main)。
            String s = ct.getName();
            for (int i = 0; i < 4; i++) {
                System.out.println(s+"线程输出"+i);
            }
        }
    }
    
    class MyThread extends Thread {
        @Override
        public void run() {
            for (int i = 0; i < 4; i++) {
                System.out.println(Thread.currentThread().getName()+"线程输出"+i);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28

    自定义线程名字2:

    public class ThreadDemo {
        public static void main(String[] args) {
            Thread t1 = new MyThread("1号");
            t1.start();
    
            Thread t2 = new MyThread("2号");
            t2.start();
    
            // 哪个线程执行它,他就返回哪个线程(当前线程对象)。
            Thread ct = Thread.currentThread();
            // 主线程调用它,拿到主线程的名字(main)。
            String s = ct.getName();
            for (int i = 0; i < 4; i++) {
                System.out.println(s+"线程输出"+i);
            }
        }
    }
    class MyThread extends Thread {
        public MyThread(String name) {
            super(name);
        }
    
        @Override
        public void run() {
            for (int i = 0; i < 4; i++) {
                System.out.println(Thread.currentThread().getName()+"线程输出"+i);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    线程的休眠方法:

    image-20221117212849038

    image-20221117213446136

    image-20221117213618193

    线程安全

    image-20221119095621485

    public class MyThread  {
        public static void main(String[] args) {
            Account account = new Account("houyiming",100000);
            new DrawThread(account,"小明").start();
            new DrawThread(account,"小红").start();
        }
    }
    
    public class DrawThread extends Thread {
        private Account acc;
    
        public DrawThread(Account acc,String name){
            super(name);
            this.acc = acc;
        }
    
        @Override
        public void run() {
            acc.drawMoney(100000);
        }
    }
    
    public class Account {
        private String CardId;
        private int money;
    
        public Account(String cardId, int money) {
            CardId = cardId;
            this.money = money;
        }
    
        public Account() {
        }
    
        public String getCardId() {
            return CardId;
        }
    
        public void setCardId(String cardId) {
            CardId = cardId;
        }
    
        public int getMoney() {
            return money;
        }
    
        public void setMoney(int money) {
            this.money = money;
        }
        public void drawMoney(int money){
            String s = Thread.currentThread().getName();
            if (this.money >= money){
                System.out.println(s+"取钱,吐出:"+money);
                this.money -= money;
                System.out.println(s+"取钱后剩余:"+this.money);
            }else{
                System.out.println(s+":余额不足 ");
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60

    线程同步

    image-20221119102737039

    同步代码块

    image-20221119102856804

    synchronized ("houyiming") { // 锁对象任意,但是要唯一。
        if (this.money >= money){
            System.out.println(s+"取钱,吐出:"+money);
            this.money -= money;
            System.out.println(s+"取钱后剩余:"+this.money);
        }else{
            System.out.println(s+":余额不足 ");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    image-20221119103754723

    synchronized (this) {
        if (this.money >= money){
            System.out.println(s+"取钱,吐出:"+money);
            this.money -= money;
            System.out.println(s+"取钱后剩余:"+this.money);
        }else{
            System.out.println(s+":余额不足 ");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    同步方法

    image-20221119104103874

    public synchronized void drawMoney(int money){
        String s = Thread.currentThread().getName();
        if (this.money >= money){
            System.out.println(s+"取钱,吐出:"+money);
            this.money -= money;
            System.out.println(s+"取钱后剩余:"+this.money);
        }else{
            System.out.println(s+":余额不足 ");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    image-20221119104428659

    Lock锁

    image-20221119105424142

    private final Lock lock = new ReentrantLock();
        public void drawMoney(int money){
            String s = Thread.currentThread().getName();
            lock.lock();
            try {
                if (this.money >= money){
                    System.out.println(s+"取钱,吐出:"+money);
                    this.money -= money;
                    System.out.println(s+"取钱后剩余:"+this.money);
                }else{
                    System.out.println(s+":余额不足 ");
                }
            } finally {
                lock.unlock();
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    线程通信

    image-20221119113015779

    image-20221119113645553

    image-20221119151745191

    线程池[重点]

    image-20221119152249597

    线程池实现的API、参数说明

    image-20221119153032458

    方式一:

    image-20221119153131164

    image-20221119153751331

    线程池实现Runnable接口

    image-20221119154045189

    public class ThreadPoolDemo {
        public static void main(String[] args) {
            // 创建线程池对象
            ExecutorService pool = new ThreadPoolExecutor(3,5,6, TimeUnit.SECONDS,
                    new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
            // 把任务交给线程池处理
            Runnable r = new MyRunnable();
            pool.execute(r);
            pool.execute(r);
            pool.execute(r);
    
            pool.execute(r);
            pool.execute(r);
            pool.execute(r);
            pool.execute(r);
            pool.execute(r);
    
            // 关闭线程池,即使任务没有完成,会丢失任务
            pool.shutdownNow();
            // 等所有任务完成之后关闭
            pool.shutdown();
        }
    }
    public class MyRunnable implements Runnable {
        @Override
        public void run() {
    
            for (int i = 0; i < 5; i++) {
                System.out.println(Thread.currentThread().getName()+": hello world : "+i);
                try {
                    Thread.sleep(100000);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    image-20221119165553873

    线程池实现Callable任务

    public class ThreadPoolDemo2 {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            // 创建线程池对象
            ExecutorService pool = new ThreadPoolExecutor(3,5,6, TimeUnit.SECONDS,
                    new ArrayBlockingQueue<>(5), Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());
            // 把任务交给线程池处理
            Future<String> f1 = pool.submit(new MyCallable(100));
            Future<String> f2 = pool.submit(new MyCallable(200));
            Future<String> f3 = pool.submit(new MyCallable(300));
            Future<String> f4 = pool.submit(new MyCallable(400));
            System.out.println(f1.get());
            System.out.println(f2.get());
            System.out.println(f3.get());
            System.out.println(f4.get());
        }
    }
    
    public class MyCallable implements Callable<String> {
        private int n;
        public MyCallable(int n){
            this.n = n;
        }
        public MyCallable(){
        }
        @Override
        public String call() throws Exception {
            int sum = 0;
            for (int i = 1; i <= n; i++) {
                sum += i;
            }
            return Thread.currentThread().getName()+"执行"+1+"到"+n+"的结果为:"+sum;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33

    Executors工具类实现线程池

    image-20221119192541768

    ExecutorService pool = Executors.newFixedThreadPool(3);
    
    • 1

    image-20221119194547796

    定时器

    image-20221119195359305

    Timer定时器

    image-20221119200635717

    public class TimerDemo1 {
        public static void main(String[] args) {
            Timer timer = new Timer(); // 定时器本身就是一个线程
            timer.schedule(new TimerTask() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"执行一次");
                }
            },3000,2000);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    ScheduledExecutorService定时器

    image-20221119200803003

    public class TimerDemo1 {
        public static void main(String[] args) {
            ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
            pool.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"11执行输出");
                    try {
                        Thread.sleep(30000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            },0,2, TimeUnit.SECONDS);
    
            pool.scheduleAtFixedRate(new TimerTask() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName()+"22执行输出");
                }
            },0,2, TimeUnit.SECONDS);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    并发并行、生命周期

    image-20221119204009237

    image-20221119204910192
    image-20221119204921360

  • 相关阅读:
    51单片机BH1750智能补光灯台灯光强光照恒流源LED控制系统
    「项目管理」制定项目计划,让项目有序进行
    漏刻有时地理信息系统LOCKGIS小程序配置说明(web-view组件、服务器域名配置、复制链接和转发功能)
    `数学` 群论
    酷开会员丨酷开系统让居家K歌变得更简单!
    [云原生] [kubernetes] 有了K8S的新基建,云原生起航了 !
    三、T100应收管理之出货立账
    【【萌新的FPGA学习之Vivado下的仿真入门-2】】
    记某同事的两次误操作导致Linux瘫痪
    二十三、SpringBoot + Jwt + Vue 权限管理系统 (4)
  • 原文地址:https://blog.csdn.net/qq_19830591/article/details/127941882