Java线程

在这里插入图片描述

在这里插入图片描述
Java线程一共6个状态。

package chapter09;

public class Java01_Thread {
    public static void main(String[] args) {
        // TODO 线程
        // Thread是线程类
        // currentThread 方法用于获取当前正在运行的线程
        // getName 方法获取线程的名字
        // main方法运行在main线程中
//        System.out.println(Thread.currentThread().getName());
//
//        // todo 创建线程
        Thread t = new Thread();
//        MyThread t = new MyThread();
//        // todo 启动线程
//        t.start();
//
//        System.out.println(Thread.currentThread().getName());
        // todo 构建线程对象时,可以只把逻辑传递给这个对象
        //      传递逻辑时,需要遵循规则: () -> { 逻辑 }
        //      ()->{} 是一个 lambda 表达式。它实现了 Runnable 接口的 run 方法
        //      Runnable 接口是一个函数式接口(只有一个抽象方法的接口),因此可以使用 lambda 表达式来简化代码。
        //      Lambda 表达式 简化了函数式接口的实现,使代码更简洁。
        //      等价写法 可以使用匿名内部类来实现
        Thread thread1 = new Thread(() -> {
            System.out.println("线程执行1");
        });
        // 等价于下面的写法
        // 构建线程对象时,可以传递实现了Runnable接口的对象,一般使用匿名类
        // Thread thread1 = new Thread(new Runnable() {
        //    @Override
        //    public void run() {
        //        System.out.println("线程执行1");
        //    }
        //});
        thread1.start();
    }
}

// TODO 声明自定义线程类
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("MyThread :" + Thread.currentThread().getName());
    }
}

package chapter09;

import java.io.IOException;

public class Java02_多线程 {
    public static void main(String[] args) throws InterruptedException {
        // TODO 多线程 - 执行方式 (串行,并发)

        // 并发执行:多个线程是独立的,谁抢到CPU执行权,谁就能执行
//        int i = 0;
//        while (i++ < 100) {
//            MyThread1 t1 = new MyThread1();
//            MyThread2 t2 = new MyThread2();
//            t1.start();
//            t2.start();
//            System.out.println("xxxxxxxxxxxx\n");
//        }

        // 串行执行:多个线程连接成串,然后按照顺序执行
        int i = 0;
        while (i++ < 100) {
            MyThread1 t1 = new MyThread1();
            MyThread2 t2 = new MyThread2();
            t1.start();
            t2.start();

            // 将线程连接成串
            t1.join();
            t2.join();

            System.out.println("xxxxxxxxxxxx\n");
        }

    }
}

class MyThread1 extends Thread {
    @Override
    public void run() {
        System.out.println("MyThread1 :" + Thread.currentThread().getName());
    }
}

class MyThread2 extends Thread {
    @Override
    public void run() {
        System.out.println("MyThread2 :" + Thread.currentThread().getName());
        try {
            Thread.sleep(1000); // 休眠1秒钟
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

四种常见的线程池

package chapter09;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Java05_Thread_Pool {
    public static void main(String[] args) {
        // TODO 线程 - 线程池
        // 所谓线程池,其实就是线程对象的容器
        // 可以根据需要,在启动时,创建一个或多个线程对象
        // Java中有4种比较常见的线程池
        // 1. 创建固定数量的线程对象
        //    ExecutorService是线程服务对象
         ExecutorService executorService = Executors.newFixedThreadPool(3);
        // 2. 根据需求动态创建线程, 创建的线程可以重复使用,只是当目前线程不够了他会动态增加线程
        executorService = Executors.newCachedThreadPool();
        // 3. 单一线程
        executorService = Executors.newSingleThreadExecutor();
        // 4. 定时调度线程, 线程有3个,但是线程在什么时候执行我们可以去定义他
        executorService = Executors.newScheduledThreadPool(3);


        for (int i = 0; i < 5; i++) {
            executorService.submit(new Runnable() {
                @Override
                public void run() {
                    System.out.println(Thread.currentThread().getName());
                }
            });
        }
    }
}

在 Java 中,创建并启动一个新的线程通常有两种主要的方式:继承 Thread 类和实现 Runnable 接口。

  1. 通过继承 Thread 类来创建一个新的线程类,并重写 Thread 类的 run() 方法。
class MyThread extends Thread {
    @Override
    public void run() {
        System.out.println("Thread is running");
    }

    public static void main(String[] args) {
        MyThread t = new MyThread();
        t.start();  //启动线程
    }
}
  1. 通过实现 Runnable 接口并实现其 run() 方法,然后将 Runnable 实例传递给 Thread 对象。
class MyRunnable implements Runnable {
    @Override
    public void run() {
        System.out.println("Thread is running");
    }

    public static void main(String[] args) {
        MyRunnable r = new MyRunnable();
        Thread t = new Thread(r);
        t.start();
    }
}
特性继承 Thread实现 Runnable 接口
继承不支持多继承,限制较大支持多继承,更灵活
代码解耦线程逻辑和线程控制耦合线程逻辑和线程控制分离
复用性不易复用易复用
共享资源需要额外处理自然适应共享资源

ps:若两个同时使用呢?

class BothRunnableThread {
    public static void main(String[] args) {
        // 创建一个匿名内部类实现 Runnable 接口的 run 方法
        new Thread(new Runnable() {
            @Override
            public void run() {
                // 这个 run 方法来自于 Runnable 接口
                System.out.println("I am runnable");
            }
        }) {
            // 创建一个匿名内部类继承 Thread 类并重写其 run 方法
            @Override
            public void run() {
                // 这个 run 方法来自于 Thread 类
                System.out.println("I am thread");
            }
        }.start();  // 启动线程
    }
}

结果是:
在这里插入图片描述

原因:
创建了一个实现了 Runnable 接口的匿名内部类的对象,然后这个Runnable类的匿名内部类的对象被传给Thread的target。
在这里插入图片描述

在这里插入图片描述
但是Thread的下面三行run方法被重写了,也就不用管Runnable类的target了,虽然Runnable类的target的run方法被重写了,所以没机会执行Runnable类的target的run方法了。
在这里插入图片描述


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Java中,线程是程序执行的基本单元,用于并发执行任务。每个线程都有自己的生命周期,包括创建、运行、阻塞和终止。线程的创建可以通过继承Thread类或实现Runnable接口来实现。 线程池则是Java中一种高效的线程管理机制,它预先创建一定数量的工作线程,并在需要执行任务时从线程池中获取线程进行处理,当任务完成后,线程会返回到线程池等待下一次调度,而不是立即结束。这样可以避免频繁地创建和销毁线程带来的开销,提高系统的性能和资源利用率。 以下是Java线程线程池的一些关键点: 1. **线程创建**: - **继承Thread类**:创建自定义线程类并重写run()方法。 - **实现Runnable接口**:创建Runnable接口的实现类,提供run()方法,然后用Thread构造函数创建Thread实例。 2. **线程状态**: - 新建(New):线程对象被创建但还未启动。 - 运行(Runnable):线程正在执行run()方法。 - 阻塞(Blocked):线程因某个条件而暂停,如I/O操作等待数据。 - 等待(Waiting):线程在调用wait()方法后,进入等待状态,直到被其他线程唤醒。 - 守护(Terminated):非守护线程完成或主线程结束,守护线程自动退出。 3. **线程池组件**: - ExecutorService:线程池的核心接口,提供了提交任务和控制线程的方法。 - ThreadPoolExecutor:实现了ExecutorService,包含核心线程数、最大线程数、任务队列等配置。 - ScheduledThreadPoolExecutor:支持定时和周期性任务。 4. **线程池的优势**: - **资源复用**:减少线程创建和销毁的开销。 - **线程管理和调度**:灵活设置线程数量、线程优先级和任务执行策略。 - **避免死锁**:由于任务有顺序地等待特定资源,减少了死锁的可能性。 - **可扩展性**:随着任务增加,线程池可以根据需要动态调整。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

重剑DS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值