JUC——多线程补充

前置可看

Java——多线程和锁_java多线程锁_北岭山脚鼠鼠的博客-CSDN博客

JUC——多线程补充_第1张图片

线程创建的三种方式

Thread、Runnable、Callable

JUC——多线程补充_第2张图片

Thread类 JUC——多线程补充_第3张图片

Runable接口

JUC——多线程补充_第4张图片

JUC——多线程补充_第5张图片

Callable接口

JUC——多线程补充_第6张图片

JUC——多线程补充_第7张图片

Lamda表达式

Lamda表达式_北岭山脚鼠鼠的博客-CSDN博客

静态代理模式(Thread类的原理)

JUC——多线程补充_第8张图片

 如下代码中

  • 真实对象和代理对象都实现了同一个接口
  • 代理对象代理真实角色

好处:

        代理对象可以做很多真实对象做不了的事情

        真实对象专注做自己的事即可 

其中多线程Thread类的底部实现原理就是静态代理模式,不过被代理的实际线程对象是由Thread来创建的。

//静态代理模式
public class StaticProxy {
    public static void main(String[] args) {
        you you=new you();

        //普通调用
        WeddingCompany weddingCompany=new WeddingCompany(you);
        weddingCompany.HappyMarry();

        //lambda表达式调用
        new WeddingCompany(you).HappyMarry();

        //多线程
        new Thread(()-> System.out.println("测试")).start();
    }
}

interface Marry{

    void HappyMarry();
}

//真实角色
class you implements Marry{

    @Override
    public void HappyMarry() {
        System.out.println("鼠鼠结婚了");
    }
}

//代理角色,帮助你结婚
class WeddingCompany implements Marry{

    //代理的对象-->真实角色
    private Marry target;

    public WeddingCompany(Marry target) {
        this.target = target;
    }

    @Override
    public void HappyMarry() {
        before();
        this.target.HappyMarry();
        after();
    }


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

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

在Java中,`Thread`类底层使用了静态代理模式来实现线程的创建和管理。静态代理模式是一种结构型设计模式,它允许你通过代理对象来控制对真实对象的访问。在`Thread`类中,`Thread`对象作为代理,用于管理真正执行线程任务的工作线程(实际的线程实例)。

具体来说,`Thread`类的静态代理模式的工作方式如下:

  • 1. **`Thread`类充当代理:** `Thread`类是代理类,它负责处理线程的生命周期、状态变化等。它提供了方法来启动、暂停、恢复、停止线程等操作。
  • 2. **实际线程对象:** 在`Thread`类中,真正执行线程任务的是一个实际的线程对象,这个线程对象通常是继承自`java.lang.Thread`的子类。这个实际的线程对象是被代理的真实对象。
  • 3. **调用`start`方法:** 当你调用`Thread`类的`start`方法时,`Thread`对象首先会执行一些必要的准备工作(例如,状态设置等),然后创建一个实际的线程对象,并调用实际线程对象的`run`方法。
  • 4. **执行线程任务:** 实际的线程对象执行线程任务。这个任务通常是在子类中的`run`方法中实现的,这是你自己定义的任务逻辑。
  • 5. **线程状态管理:** `Thread`类会在合适的时机管理线程的状态变化,例如,当线程启动时,`Thread`对象会将线程状态设置为"RUNNABLE",当线程执行完毕时,`Thread`对象会将线程状态设置为"TERMINATED"。

总之,`Thread`类在底层使用静态代理模式,通过代理对象管理实际线程对象的创建、启动、暂停、停止等操作,以实现对线程的管理和控制。这种方式使得线程的管理更加便捷,同时也遵循了代理模式的思想。

线程状态—五大状态

JUC——多线程补充_第9张图片

JUC——多线程补充_第10张图片 JUC——多线程补充_第11张图片

停止线程 

JUC——多线程补充_第12张图片

//测试stop
//1.建议线程正常停止--->利用次数,不建议死循环
//2.建议使用标志位--->设置一个标志位
//3.不要使用stop或者destory
public class TestStop implements Runnable{
    //1.设置一个标志位
    private boolean flag=true;
    @Override
    public void run() {
        int i=0;
        while (flag){
            System.out.println("run...Thread"+i++);
        }
    }
    //2.设置公开方法停止线程
    public void stop(){
        this.flag=false;
    }

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

        for(int i=0;i<1000;i++)
        {
            System.out.println("main"+i);
            if(i==900){
                //调用stop方法切换标志位,让线程停止
                testStop.stop();
                System.out.println("线程停止了");
            }
        }


        System.in.read();
    }
}

 线程休眠_sleep

JUC——多线程补充_第13张图片

 线程礼让_yeild 

JUC——多线程补充_第14张图片

//测试礼让线程
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() +"线程停止执行");
    }
}

线程强制执行_join

JUC——多线程补充_第15张图片

线程状态观测 

JUC——多线程补充_第16张图片

//观察测试线程的状态
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) {
                    throw new RuntimeException(e);
                }
            }
            System.out.println("//");
        });


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

        //观察启动后
        thread.start();//启动线程
         state = thread.getState();
        System.out.println(state);//run

        while(state!=Thread.State.TERMINATED){//只要线程不终止,就一直输出状态
            Thread.sleep(100);
            state=thread.getState();//更新线程状态
            System.out.println(state);//输出状态
        }
    }
}

 JUC——多线程补充_第17张图片

 线程优先级

JUC——多线程补充_第18张图片

 守护(daemon)线程

JUC——多线程补充_第19张图片

线程同步

多个线程操作同一个资源。

JUC——多线程补充_第20张图片

JUC——多线程补充_第21张图片

同步方法及同步块

JUC——多线程补充_第22张图片

弊端

JUC——多线程补充_第23张图片

同步块

JUC——多线程补充_第24张图片

CopyOnWriteArrayList

java的JUC并发包下安全类型的集合

/**
 * 测试JUC安全类型的集合
 */
public class TestJUC {
    public static void main(String[] args) throws InterruptedException {
        CopyOnWriteArrayList list=new CopyOnWriteArrayList();

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

安全问题得到解决

 

 在其实现源码里面可以看见有两个JUC的关键词,volatile保证唯一,transient保证序列化的.

JUC——多线程补充_第25张图片

 死锁

JUC——多线程补充_第26张图片

死锁形成的四个条件: 互斥/请求与保持/不可剥夺条件/循环等待条件。 

JUC——多线程补充_第27张图片

Lock(锁)

JUC——多线程补充_第28张图片

ReentrantLock可重入锁类.

在CopyOnWriteArrayList里面就有这个类

JUC——多线程补充_第29张图片 JUC——多线程补充_第30张图片

/**
 * 测试lock锁
 */
public class TestLock {
    public static void main(String[] args) {
        TestLock2 testLock2=new TestLock2();
        new Thread(testLock2).start();
        new Thread(testLock2).start();
        new Thread(testLock2).start();
    }
}
class TestLock2 implements Runnable{
    int tickNums=10;

    //定义锁
   private final  ReentrantLock lock=new ReentrantLock();


    @Override
    public void run() {
        while(true){
            try{
                //此处加锁
                lock.lock();
                if(tickNums>0){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        throw new RuntimeException(e);
                    }
                    System.out.println(tickNums--);
                }else
                {
                    break;
                }
            }finally {
                //解锁
                lock.unlock();
            }
        }
    }
}

 

Synchronized和Lock的对比 

JUC——多线程补充_第31张图片

 线程协作和通信

生产者和消费者模式

JUC——多线程补充_第32张图片

JUC——多线程补充_第33张图片 JUC——多线程补充_第34张图片

管程法

JUC——多线程补充_第35张图片

 

代码实现网上大把.就是两个关键点,一个是消费数量的临界值,第二个就是wait 和notify的使用.

信号灯法

上面管程法用的是容器,这里用的是标志位,但是也相当于是容量为1的容器.

线程池

JUC——多线程补充_第36张图片

 就像是IO的缓冲池,Mybatis的缓存,数据库的连接池,JVM的常量池

JUC——多线程补充_第37张图片

 

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

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

        //2.关闭连接
        service.shutdown();
    }
}

class MyThread implements Runnable{


    @Override
    public void run() {
            System.out.println(Thread.currentThread().getName());
    }
}

JUC——多线程补充_第38张图片

你可能感兴趣的:(JVM+JUC,java,多线程)