多线程有这一篇就够(超详细万字总结)

1 线程简介

1.1多任务

多线程有这一篇就够(超详细万字总结)_第1张图片

看起来是多个任务一起做,但实际上我们的大脑在同一时间,依旧只是在做一件事 

1.2多线程

多线程(multithreading),是指从软件或者硬件上实现多个线程并发执行的技术。具有多线程能力的计算机因有硬件支持而能够在同一时间执行多于一个线程,进而提升整体处理性能。

1.3普通方法调用 和 多线程的区别

多线程有这一篇就够(超详细万字总结)_第2张图片

1.4进程和线程

一个进程可以包括多个线程 最直观地理解 就是在看视频的时候 可以同时 看到视频 听到声音 看到弹幕等等 注意:很多多线程是模拟出来的,真正的多线程指的是拥有多个cpu,即多核。模拟出来的多线程 通常情况下是cpu切换的很快 造成了多线程的错觉 。对同一份资源进行操作时,会存在资源抢夺的问题,需要加入并发控制。

2 线程创建(重要)

2.1三种创建方式

多线程有这一篇就够(超详细万字总结)_第3张图片

2.2Thread

第一步:创建线程类继承Thread类

第二步:重写run()方法 编写线程执行体

第三步:创建线程对象 执行start()方法 启动线程

上代码

package com.kuang.demo1;
//创建线程方式一:继承Thread类,重写run()方法,调用start()方法
public class TestThread1 extends Thread{
    @Override
    public void run(){
        //run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("我在看代码---"+i);
        }
    }

    public static void main(String[] args) {
        //主线程

        //创建一个线程对象
        TestThread1 testThread1 = new TestThread1();

        //开启线程
        testThread1.start();

        for (int i = 0; i < 200; i++) {
            System.out.println("我在学习主线程--"+i);
        }
    }
}

 结果:

多线程有这一篇就够(超详细万字总结)_第4张图片

多线程有这一篇就够(超详细万字总结)_第5张图片

  注意,线程开启并不一定立即执行,由cpu调度执行

2.3Runnable

第一步:定义MyRunnable类实现Runnable接口

第二步:实现run方法,编写线程执行体

第三步:创建线程对象 调用start()启动线程

代码:

package com.kuang.demo1;
//创建线程方式二:实现Runnable接口 重写run方法 执行线程需要丢入runnable接口实现类 调用start方法

public class TestThread2 implements Runnable{

    @Override
    public void run() {
        //run方法线程体
        for (int i = 0; i < 200; i++) {
            System.out.println("我在看代码---"+i);
        }
    }

    public static void main(String[] args) {
        //创建runnable接口的实现类对象
        TestThread2 testThread2 = new TestThread2();
        //创建线程对象,通过线程对象来开启线程(代理)
        Thread thread1 = new Thread(testThread2);

        thread1.start();
        //前三行 等价于 下面 一行
        new Thread(testThread2).start();

        for (int i = 0; i < 1000; i++) {
            System.out.println("我在学习主线程--"+i);
        }
    }
}

 结果:

多线程有这一篇就够(超详细万字总结)_第6张图片

比较:

多线程有这一篇就够(超详细万字总结)_第7张图片

3 初识并发问题

3.1购买火车票例子

package com.kuang.demo1;
//并发问题 火车票购买例子
public class TestThread3 implements Runnable{
    //票数
    private int ticketNums = 10;
    @Override
    public void run() {
        while(true){
            if (ticketNums<=0){
                break;
            }
             try {
                Thread.sleep(200);//延时效果
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNums--+"张票");
        }
    }

    public static void main(String[] args) {
        TestThread3 ticket = new TestThread3();
        new Thread(ticket,"小明").start();
        new Thread(ticket,"老师").start();
        new Thread(ticket,"黄牛").start();


    }
}

运行后我们发现

多线程有这一篇就够(超详细万字总结)_第8张图片

相信我们已经发现了并发问题的所在 

当多个线程操作同一资源的情况下,线程不安全,数据紊乱。如何解决?在下文会提到

4 案例龟兔赛跑

多线程有这一篇就够(超详细万字总结)_第9张图片

package com.kuang.demo1;

//模拟龟兔赛跑
public class Race implements Runnable{
    private static String winner;
    @Override
    public void run() {
        for (int i = 0; i <= 100; i++) {
            //模拟兔子休息
            if (Thread.currentThread().getName().equals("兔子")&&i%10==0){
                try {
                    Thread.sleep(2);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            //判断比赛是否结束
            boolean flag = gameOver(i);
            if (flag){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
        }
    }

    //判定是否完成比赛
    private boolean gameOver(int steps){
        //判断是否有胜利者
        if (winner!=null){
            return true;
        }else {
            if (steps>=100){
                winner=Thread.currentThread().getName();
                System.out.println("winner is "+winner);
                return true;
            }
        }
        return false;
    }

    public static void main(String[] args) {
        Race race = new Race();

        new Thread(race,"兔子").start();
        new Thread(race,"乌龟").start();
    }
}

 多线程有这一篇就够(超详细万字总结)_第10张图片

 多线程有这一篇就够(超详细万字总结)_第11张图片

 5 Callable

package com.kuang.demo1;

import java.util.concurrent.*;

public class TestCallable implements Callable {
    @Override
    public Boolean call() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println("我在看代码---"+i);
        }
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestCallable testCallable = new TestCallable();
        //创建执行服务
        ExecutorService ser = Executors.newFixedThreadPool(1);
        //提交执行
        Future result1 = ser.submit(testCallable);
        //获得结果
        boolean r1 =result1.get();
        //关闭服务
        ser.shutdownNow();

        for (int i = 0; i < 200; i++) {
            System.out.println("我在学习主线程--"+i);
        }
    }
}

Callable可以定义返回值,抛出异常 相比Runnable 更加安全 工作常用。

6 静态代理

package com.kuang.demo1;
//静态代理模式总结:
//真实对象和代理对象都要实现同一接口
//代理对象要代理真实角色,他还可以做些额外的事情
public class StacticProxy {
    public static void main(String[] args) {
        WeddingCompany weddingCompany = new WeddingCompany(new You("小明"));
        weddingCompany.HappyMarry();

    }
}
interface Marry{

    void HappyMarry();
}
//真实角色
class You implements Marry{
    private String name;
    You(){
    }
    You(String name){
        this.name=name;
    }
    @Override
    public void HappyMarry() {
        System.out.println(name+"结婚了,超开心!");
    }
}
//代理角色,帮助你结婚
class WeddingCompany implements Marry{
    //代理谁-》真实目标角色
    private Marry target;
    WeddingCompany(Marry target){
        this.target=target;
    }
    @Override
    public void HappyMarry() {
        before();
        target.HappyMarry();//这就是真实对象
        after();
    }

    private void after() {
        System.out.println("结婚后,收尾款");
    }

    private void before() {
        System.out.println("结婚前,布置现场");
    }
}

多线程有这一篇就够(超详细万字总结)_第12张图片

 7 线程状态(重要)

多线程有这一篇就够(超详细万字总结)_第13张图片

7.1线程停止

多线程有这一篇就够(超详细万字总结)_第14张图片

package com.kuang.demo1;
//1.建议线程正常停止-> 利用次数,不建议死循环
//2. 建议使用标志位-> 设置一个标志位
//3. 不要使用jdk弃用的方法
public class TestStop implements Runnable{
    //设置标志位
    private boolean flag = true;
    @Override
    public void run() {
        int i = 0;
        while(flag){
            System.out.println("run...Thread"+i++);
        }
    }

    //转换标志位
    public void stop(){
        this.flag=false;
    }

    public static void main(String[] args) {
        TestStop testStop = new TestStop();
        new Thread(testStop).start();

        for (int i=0;i<1000;i++){
            System.out.println("main"+i);
            if (i==900){
                testStop.stop();
                System.out.println("线程该停止了");
            }
        }
    }
}

 多线程有这一篇就够(超详细万字总结)_第15张图片

7.2线程休眠

多线程有这一篇就够(超详细万字总结)_第16张图片

package com.kuang.demo1;
//模拟网络延时:放大问题的发生性
public class TestSleep implements Runnable{
    private int ticketNums = 10;
    @Override
    public void run() {
        while(true){
            if (ticketNums<=0){
                break;
            }
            try {
                Thread.sleep(200);//延时效果
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNums--+"张票");
        }
    }

    public static void main(String[] args) {
        TestThread3 ticket = new TestThread3();
        new Thread(ticket,"小明").start();
        new Thread(ticket,"老师").start();
        new Thread(ticket,"黄牛").start();


    }
}

 多线程有这一篇就够(超详细万字总结)_第17张图片

 如此让我们意识到线程并发问题

7.3线程礼让

多线程有这一篇就够(超详细万字总结)_第18张图片

多线程有这一篇就够(超详细万字总结)_第19张图片

package com.kuang.demo1;
//礼让不一定成功 看cpu心情
public class TestYield {

    public static void main(String[] args) {
        MyYield myYield = new MyYield();

        new Thread(myYield,"a").start();
        new Thread(myYield,"b").start();
    }

}
class  MyYield implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"线程开始执行");
        Thread.yield();
        System.out.println(Thread.currentThread() .getName()+"线程停止");
    }
}

 多线程有这一篇就够(超详细万字总结)_第20张图片

7.4线程强制执行

多线程有这一篇就够(超详细万字总结)_第21张图片

package com.kuang.demo1;
//测试Join 想象成插队
public class Testjoin implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("线程vip来了"+i);
        }
    }

    public static void main(String[] args) throws InterruptedException {

        Testjoin testjoin = new Testjoin();

        Thread thread = new Thread(testjoin);
        thread.start();

        for (int i = 0; i < 500; i++) {
            if (i==200){
                thread.join();//插队
            }
            System.out.println("main"+i);
        }
    }
}

 多线程有这一篇就够(超详细万字总结)_第22张图片

 多线程有这一篇就够(超详细万字总结)_第23张图片

 7.5观察线程状态

package com.kuang.demo1;

public class TestState {
    public static void main(String[] args) throws InterruptedException {
        Thread thread = new Thread(()->{
            for (int i = 0; i < 5; i++) {
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            System.out.println("线程结束了");
        });

        //观察状态
        Thread.State state = thread.getState();
        System.out.println(state);

        thread.start();
        state=thread.getState();
        System.out.println(state);

        while(state!=Thread.State.TERMINATED){
            Thread.sleep(100);
            state=thread.getState();
            System.out.println(state);
        }
    }
}

多线程有这一篇就够(超详细万字总结)_第24张图片

 多线程有这一篇就够(超详细万字总结)_第25张图片

 7.6线程优先级

多线程有这一篇就够(超详细万字总结)_第26张图片

首先知道一点 从1-10 等级越高 cpu分配的权重越大 越容易被分派资源 但不绝对

package com.kuang.demo1;
//测试线程的优先级
public class TestPriority {
    public static void main(String[] args) {
        //测试主线程的优先级
        System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());

        MyPriority myPriority = new MyPriority();

        Thread t1 = new Thread(myPriority);
        Thread t2 = new Thread(myPriority);
        Thread t3 = new Thread(myPriority);
        Thread t4 = new Thread(myPriority);
        Thread t5 = new Thread(myPriority);
        Thread t6 = new Thread(myPriority);

        //先设置优先级 再启动
        t1.start();

        t2.setPriority(1);
        t2.start();

        t3.setPriority(4);
        t3.start();

        t4.setPriority(Thread.MAX_PRIORITY);//10
        t4.start();

        t5.setPriority(-1);
        t5.start();

        t6.setPriority(11);
        t6.start();
    }
}
class MyPriority implements Runnable{

    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());

    }
}

多线程有这一篇就够(超详细万字总结)_第27张图片

等级是从1到10 否则会报错的。

 多线程有这一篇就够(超详细万字总结)_第28张图片

7.7守护线程

多线程有这一篇就够(超详细万字总结)_第29张图片

package com.kuang.demo1;
//测试守护线程
//上帝守护你
public class TestDaemon {
    public static void main(String[] args) {
        God god = new God();
        you you1 = new you();


        Thread thread = new Thread(god);
        thread.setDaemon(true);

        thread.start();//上帝守护线程启动

        new Thread(you1).start();//你 用户线程启动
    }
}
class God implements Runnable{

    @Override
    public void run() {
        while(true){
            System.out.println("上帝保佑着你");
        }
    }
}
class you implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 36500; i++) {
            System.out.println("开心的活着");
        }
        System.out.println("-====goodbye! world!");//hello world;

    }
}

 多线程有这一篇就够(超详细万字总结)_第30张图片

 多线程有这一篇就够(超详细万字总结)_第31张图片

理论来说上帝线程不应该结束 但由于我们设置为守护线程 要守护的线程结束后 该线程跑了一会 也结束了。 

8 线程同步(重点 难点)

8.1 线程同步机制

多线程有这一篇就够(超详细万字总结)_第32张图片

 多线程有这一篇就够(超详细万字总结)_第33张图片

多线程有这一篇就够(超详细万字总结)_第34张图片

8.2三大不安全案例

不安全的火车站买票实例

public class UnSafeBuyTicket {
    public static void main(String[] args) {
        BuyTicket buyTicket = new BuyTicket();

        new Thread(buyTicket,"苦逼的我").start();
        new Thread(buyTicket,"可恶的黄牛党").start();
        new Thread(buyTicket,"牛逼的你们").start();
    }
}
class BuyTicket implements Runnable{


    //票
   private int ticketNums = 10;
   boolean flag = true;
    @Override
    public void run() {
        //买票
        while(flag){
            try {
                buy();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void buy() throws InterruptedException {
        //判断是否由票
        if (ticketNums<=0){
            flag=false;
            return;
        }
        //模拟延时
        Thread.sleep(100);
        System.out.println(Thread.currentThread().getName()+"拿到第"+ticketNums--+"张票");

    }
}

多线程有这一篇就够(超详细万字总结)_第35张图片

 不安全的银行取钱实例

package com.kuang.demo1;
//不安全的取钱
//两人去取钱 账户
public class UnSafeBank {
    public static void main(String[] args) {
        Account account = new Account(100,"结婚基金");

        Drawing you = new Drawing(account,50,"你");
        Drawing yourFriend = new Drawing(account,100,"yourFriend");
        you.start();
        yourFriend.start();
    }
}
class Account{
    int money;//余额
    String name;//卡号

    public Account(int money, String name) {
        this.money = money;
        this.name = name;
    }
}
class Drawing extends Thread{
    Account account ;//账户
    //取了多少钱
    int drawingMoney;
    //现在由多少钱
    int nowMoney;
    public Drawing(Account account,int drawingMoney,String name){
        super(name);
        this.account=account;
        this.drawingMoney=drawingMoney;

    }

    //取钱
    public void run(){
        //判断有没有钱
        if (account.money-drawingMoney<0){
            System.out.println(Thread.currentThread().getName()+"钱不够");
            return;
        }
        //sleep可以放大问题的发生
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        account.money = account.money-drawingMoney; //很好理解

        nowMoney=nowMoney+drawingMoney;

        System.out.println(account.name+"余额为"+account.money);

        System.out.println(this.getName()+"手里的钱"+nowMoney);
    }

}

多线程有这一篇就够(超详细万字总结)_第36张图片

 一共存了100 现在共有150 明显发生了Bug

不安全的集合实例

package com.kuang.demo1;

import java.util.ArrayList;
import java.util.List;

//线程不安全的集合
public class UnsafeList {
    public static void main(String[] args) {
        List list = new ArrayList<>();

        for (int i = 0; i < 1000; i++) {
            new Thread(()->{
                list.add(Thread.currentThread().getName());
            }).start();
        }
        System.out.println(list.size());
    }
}

这里我们应该得到数字1000 但运行后结果是

多线程有这一篇就够(超详细万字总结)_第37张图片

 8.3同步方法及同步块

多线程有这一篇就够(超详细万字总结)_第38张图片

多线程有这一篇就够(超详细万字总结)_第39张图片

安全的买票实例

package com.kuang.demo1;

public class UnSafeBuyTicket {
    public static void main(String[] args) {
        BuyTicket buyTicket = new BuyTicket();

        new Thread(buyTicket,"苦逼的我").start();
        new Thread(buyTicket,"可恶的黄牛党").start();
        new Thread(buyTicket,"牛逼的你们").start();
    }
}
class BuyTicket implements Runnable{


    //票
   private int ticketNums = 10;
   boolean flag = true;
    @Override
    public void run() {
        //买票
        while(flag){
            try {
                buy();
                //模拟延时
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
    //synchronized 加了该关键字后 方法就变成了同步方法 实现了锁
    private synchronized void buy()  {
        //判断是否由票
        if (ticketNums<=0){
            flag=false;
            return;
        }

        System.out.println(Thread.currentThread().getName()+"拿到第"+ticketNums--+"张票");

    }
}

 只需要加上关键字 synchronized 再改变sleep()的位置即可

多线程有这一篇就够(超详细万字总结)_第40张图片

程序从 各个线程之间“抢票” 变为了 排队购票 就实现了线程的安全 

安全的银行取钱实例

package com.kuang.demo1;
//不安全的取钱
//两人去取钱 账户
public class UnSafeBank {
    public static void main(String[] args) {
        Account account = new Account(100,"结婚基金");

        Drawing you = new Drawing(account,50,"你");
        Drawing yourFriend = new Drawing(account,50,"yourFriend");
        you.start();
        yourFriend.start();
    }
}
class Account{
    int money;//余额
    String name;//卡号

    public Account(int money, String name) {
        this.money = money;
        this.name = name;
    }
}
class Drawing extends Thread{
    Account account ;//账户
    //取了多少钱
    int drawingMoney;
    //现在由多少钱
    int nowMoney;
    public Drawing(Account account,int drawingMoney,String name){
        super(name);
        this.account=account;
        this.drawingMoney=drawingMoney;

    }

    //取钱

    public void run() {
        //判断有没有钱
        synchronized (account) {
            if (account.money - drawingMoney < 0) {
                System.out.println(Thread.currentThread().getName() + "钱不够");
                return;
            }
            //sleep可以放大问题的发生
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            account.money = account.money - drawingMoney; //很好理解

            nowMoney = nowMoney + drawingMoney;

            System.out.println(account.name + "余额为" + account.money);

            System.out.println(this.getName() + "手里的钱" + nowMoney);
        }
    }

}

多线程有这一篇就够(超详细万字总结)_第41张图片

安全的集合实例

package com.kuang.demo1;

import java.util.ArrayList;
import java.util.List;

//线程不安全的集合
public class UnsafeList {
    public static void main(String[] args) throws InterruptedException {
        List list = new ArrayList<>();

        for (int i = 0; i < 1000; i++) {
            new Thread(()->{
                synchronized (list) {
                    list.add(Thread.currentThread().getName());
                }
            }).start();
        }
        Thread.sleep(300);
        System.out.println(list.size());
    }
}

 多线程有这一篇就够(超详细万字总结)_第42张图片

8.4CopyOnWriteArrayList

这是一个线程安全的集合类 (了解)

package com.kuang.demo1;

import java.util.concurrent.CopyOnWriteArrayList;

//测试Juc安全类型的集合
public class TestJUC {
    public static void main(String[] args) throws InterruptedException {
        CopyOnWriteArrayList list = new CopyOnWriteArrayList();
        for (int i = 0; i < 1000; i++) {
            new Thread(()->{
                list.add(Thread.currentThread().getName());
            }).start();
        }
        Thread.sleep(300);

        System.out.println(list.size());
    }

}

多线程有这一篇就够(超详细万字总结)_第43张图片

 8.5死锁

多线程有这一篇就够(超详细万字总结)_第44张图片

多线程有这一篇就够(超详细万字总结)_第45张图片 8.6Lock(锁)

多线程有这一篇就够(超详细万字总结)_第46张图片

 实例我们还用买票系统

package com.kuang.demo1;

import java.util.concurrent.locks.ReentrantLock;

public class TestLock {
    public static void main(String[] args) {
        TestLock2 testLock2 = new TestLock2();

        new Thread(testLock2,"黄牛1").start();
        new Thread(testLock2,"黄牛2").start();
        new Thread(testLock2,"黄牛3").start();
    }
}
class TestLock2 implements Runnable{
    int tickNums = 100;

    //定义Lock锁
    private ReentrantLock lock = new ReentrantLock();
    @Override
    public void run() {
        while(true){

            try {
                lock.lock();//加锁

                if (tickNums > 0) {

                    System.out.println(Thread.currentThread().getName()+"拿到了第"+tickNums--+"张票");
                } else {
                    break;
                }
            }finally {
                //解锁
                lock.unlock();
            }
        }
    }
}

 多线程有这一篇就够(超详细万字总结)_第47张图片

 

 多线程有这一篇就够(超详细万字总结)_第48张图片

 多线程有这一篇就够(超详细万字总结)_第49张图片

9 线程协作 

9.1生产者消费者问题

多线程有这一篇就够(超详细万字总结)_第50张图片

多线程有这一篇就够(超详细万字总结)_第51张图片

多线程有这一篇就够(超详细万字总结)_第52张图片

多线程有这一篇就够(超详细万字总结)_第53张图片

多线程有这一篇就够(超详细万字总结)_第54张图片

true 就等待 false 就去唤醒  

9.2信号灯法

package com.kuang.demo1;

public class TestPc2 {
    public static void main(String[] args) {
        Tv tv = new Tv();
        new Player(tv).start();
        new Watcher(tv).start();
    }
}
//生产者->演员
class Player extends Thread{
    Tv tv;
    public Player(Tv tv){
        this.tv=tv;
    }
    
    @Override
    public void run(){
        for (int i = 0; i < 20; i++) {
            if (i%2==0){
                try {
                    this.tv.play("快乐大本营播放着");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }else {
                try {
                    this.tv.play("广告");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
//消费者->观众
class Watcher extends Thread{
    Tv tv;
    public Watcher(Tv tv){
        this.tv=tv;
    }
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            try {
                tv.watch();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}
//产品->节目
class Tv{
    String voice;
    boolean flag = true;
     //表演
    public synchronized void play(String voice) throws InterruptedException {
        if (!flag){
            this.wait();
        }
        System.out.println("演员表演了"+voice);
        //通知观众观看
        this.notifyAll();//通知唤醒
        this.voice=voice;
        this.flag=!this.flag;
    }

    public synchronized void watch() throws InterruptedException {
        if (flag){
            this.wait();
        }
        System.out.println("观看了"+voice);
        //通知演员表演
        this.notifyAll();
        this.flag=!this.flag;

    }
}

多线程有这一篇就够(超详细万字总结)_第55张图片

可以理解为 演员表演了什么 观众就观看什么 且顺序符合逻辑

9.3线程池

多线程有这一篇就够(超详细万字总结)_第56张图片 多线程有这一篇就够(超详细万字总结)_第57张图片

package com.kuang.demo1;

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

//测试线程池
public class TestPool {
    public static void main(String[] args) {
        //1.创建服务,创建线程池
        //newFixedThreadPool 参数为线程池大小
        ExecutorService service = Executors.newFixedThreadPool(10);

        //执行
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());
        service.execute(new MyThread());

        //2.关闭链接
        service.shutdownNow();
    }
}
class MyThread implements Runnable{

    @Override
    public void run() {

            System.out.println(Thread.currentThread().getName());

    }
}

 多线程有这一篇就够(超详细万字总结)_第58张图片

 ================================我是分割线 ================================

本篇为学习狂神讲的多线程的笔记 屏幕前的你如果想跟着视频再敲一遍 地址如下:

【狂神说Java】多线程详解_哔哩哔哩_bilibili

 不要忘记三连哦!(●'◡'●)

你可能感兴趣的:(java,后端)