多线程进一步学习

8 篇文章 0 订阅

多线程进一步学习

一、多线程原理的深度剖析

静态代理原理

代理模式是面向对象编程中比较常用的设计模式

是SpringAOP的底层,使被代理的真实角色更加纯粹,不用关注一些公共的业务。公共业务交给代理角色,实现角色分工,方便管理

代理模式角色:
在这里插入图片描述
具体展示代理实例,比抽象理解更清晰

对多线程而言,初步学习静态代理

对于程序员而言,购置一台性价比不错的电脑很有必要,这是就有中间代理人会帮你购置赚取差价。代理电脑示例

1、角色分析:

  • 真实角色,【被代理的角色】电脑厂商
  • 代理角色,中间代理人
  • 代理对象,即电脑抽象接口
  • 客户,买电脑的人

2、代码实现:

//thirdDay;

public class staticProxy {
    public static void main(String[] args) {
        //多线程的Lamda表达式 ()->
        //静态代理相当于多线程底部的实现原理
        new Thread( ()->System.out.println("你好") ).start();
        new computerFactory(new proxySale()).proxyComputer();
//        computerFactory computerFactory = new computerFactory(new proxySale());
//        computerFactory.proxyComputer();
    }
}
//代理对象,电脑抽象接口
abstract interface computer{
    void proxyComputer();
}
//代理角色,中间代理人
class proxySale implements computer{

    @Override
    public void proxyComputer() {
        System.out.println("已经售出一台电脑!");
    }
}
//真实角色,被代理的角色电脑厂商
class computerFactory implements computer{

    //厂商的代理人
    private proxySale saler;
    public computerFactory(proxySale saler){
        this.saler = saler;
    }

    @Override
    public void proxyComputer() {
        before();
        this.saler.proxyComputer();
        after();
    }
    
    private void before() {
        System.out.println("寻找代理---->");
    }
    private void after() {
        System.out.println("获得一台电脑利润!");
    }

}

3、总结一下:

真实角色和代理角色都要实现同一个接口,代理角色要代理真实角色的任务。
代理模式优点:真实角色可以专注自己的事情,代理角色实现真实角色做不了的很多事情。实现分工,方便管理。

静态代理相当于多线程底部的实现原理

  new Thread( ()->System.out.println("你好") ).start();
  new computerFactory(new proxySale()).proxyComputer();

二、Lamda表达式

函数式编程中使用

通俗解释:一个接口中,只包含一个抽象方法

eg:new Thread(()->System.out.println("多线程学习").start());

因为接口只有一个抽象方法,因此可以省略无意义的、只写有意义的代码

为什么使用它?

避免匿名内部类定义过多。简洁,留下核心代码

内部类?:静态内部类,局部内部类,匿名内部类

//Lamda表达式;

/**
 * Lamda表达式测试
 */
public class testLamda01 {
    //3.静态内部类
    static class people2 implements doSomething{
        @Override
        public void clean() {
            System.out.println("two people");
        }
    }
    public static void main(String[] args) {
        doSomething p1 = new people();
        p1.clean();


        doSomething p2 = new people2();
        p2.clean();


        //4.局部内部类
        class people3 implements doSomething{
            @Override
            public void clean() {
                System.out.println("three people");
            }
        }
        doSomething p3 = new people3();
        p3.clean();


        //5.匿名内部类,借助接口或者父类实现
        doSomething p4 = new doSomething() {
            @Override
            public void clean() {
                System.out.println("four people");
            }
        };
        p4.clean();


        //6.Lamda表达式 简化() ->{   };空参
        doSomething p5 = () ->{
            System.out.println("five people");
        };
        p5.clean();

    }
}

//2.实现类
class people implements doSomething{
    @Override
    public void clean() {
        System.out.println("one people");
    }
}


//1.定义一个函数式接口
interface doSomething{
    void clean();
}

真正简化Lamda代码

在实现类的方法体中只有一行代码,可省略参数类型、()、{}

方法体中有 >=2行代码,参数类型可省略,()、{}不可省略

实现购物代码:

//Lamda表达式;

public class realLamdaTest {
    public static void main(String[] args) {
        //真正Lamda 简化代码
        //省略参数类型、{}、()
        shopping sop = nums -> System.out.println(nums +" bag(s) was bought.");
        sop.bag(2);
    }
}
interface shopping{
    void bag(int nums);
}

三、线程状态(五种)

在这里插入图片描述

线程方法:

【查看JDK文档】

setPriority(int newPriority) 更改线程的优先级
static void sleep(long millions) 在指定的毫秒数内让当前正在执行的线程休眠
void join() 等待该线程终止
static void yield() 暂停当前正在执行的线程对象,并执行其他线程
void interrupt() 中断线程
boolean inAlive() 判断线程是否为活动状态
  • 线程停止

    代码实现停止,设置自己线程暂停

//线程停止;

public class stopThreadUse implements Runnable{
    private boolean flag = true;

    @Override
    public void run() {
        int i = 0;
        while (flag){
            System.out.println("running thread---> " + i++);
        }
    }

    //暂停方法
    public void tempStop(){
        this.flag = false;
    }

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

        for (int i = 0; i < 500; i++) {
            System.out.println("main线程执行" + i);
            if (i == 400){
                 stop.tempStop();
                 System.out.println("stopThreadUse线程停止!");
            }
        }
    }
}

一般不用stop/destory等过时不推荐的方法,而使用flag标识位让它停下来


  • 线程休眠 sleep()

存在InterruptedException异常,线程不安全

sleep()时间达到后进入就绪状态

sleep可以模拟网络延时,倒计时…

1.实现睡眠模拟倒计时

//线程休眠;
public class sleepTest {
    //模拟倒计时
    public static void countDown() throws InterruptedException {
        int nums = 8;
        while (true){
            Thread.sleep(1000);
            System.out.println(nums--);
            if (nums < 0){
                break;
            }
        }
    }


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

2.系统打印时间:

//线程休眠;

import java.text.SimpleDateFormat;
import java.util.Date;

    //系统时间打印
    public static void printTime() throws InterruptedException {
        //get系统当前时间
        Date date = new Date(System.currentTimeMillis());
        while (true){
            Thread.sleep(1000);
            System.out.println(new SimpleDateFormat("HH:mm:ss").format(date));
            date = new Date(System.currentTimeMillis());//更新时间
        }
    }

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

  • 线程礼让 yield()

让当前正在执行的线程暂停,但不阻塞,让其他线程先执行。从运行状态—>就绪状态

//线程礼让;

public class yieldTest {
    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()+"--->结束");
    }
}

Thread.yield()线程礼让不一定成功,每次结果都不一样,看CPU心情


  • 线程强制执行 join()

该线程遇到 join()方法,强制被暂停,先执行其他线程,直到其他线程执行完毕再接着执行

//线程强制执行;

public class joinTest implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("joinTest线程VIP"+i);
        }
    }
    
    public static void main(String[] args) throws InterruptedException {
        joinTest joinTest = new joinTest();
        Thread thread = new Thread(joinTest);
        thread.start();

        for (int i = 0; i < 500; i++) {
            if (i == 200) {
                //joinTest线程插队,强行进来
                thread.join();
            }
            System.out.println("main线程"+i);
        }

    }
}
  • 总结:
  1. 线程死后不能再二次调用
  2. 要判断线程状态?使用.getStatue() 方法

四、线程的优先级

getPriority()  得到该线程的优先级
setPriority()   设置更改此线程的优先级

相当于Java线程提供一个调度器,监控启动后进入就绪状态的线程调度方法

线程优先级范围 1~10

Thread.MAX_PRIORITY=10>Thread.NORM_PRIORITY=5>Thread.MIN_PRIORITY=1

优先级设定一般在start()方法之前

优先级低只是获得调度的概率低,并不是不会调用,看CPU的调度

五、守护线程

线程状态分类:

  1. 守护线程(GC垃圾回收线程)
  2. 用户线程(main主线程、自己手动创建的线程)
  • 守护线程

JVM不用等待守护线程执行完毕

当主线程运行,GC线程一起运行;当主线程销毁,GC线程一起销毁

  • 用户线程

JVM必须确保用户线程执行完毕

如果主线程销毁,用户线程继续运行且互不影响

代码区别演示:

//守护线程;

public class daemonTest {
    public static void main(String[] args) {
        person person = new person();
        God god = new God();

        Thread thread = new Thread(god);
        thread.setDaemon(true); //将此线程标记为 daemon线程,守护线程
        thread.start();
        

        new Thread(person).start(); //用户线程手动启动
    }
}

//用户线程
//如果主线程销毁,用户线程继续运行且互不影响
class person implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 36500; i++) {
            System.out.println("Hello World!");
        }
        System.out.println("person over");
    }
}

//守护线程
//当主线程运行,GC线程一起运行;当主线程销毁,GC线程一起销毁
class God implements Runnable{

    @Override
    public void run() {
        System.out.println("God is always here!");
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

皮皮怪鼠

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

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

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

打赏作者

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

抵扣说明:

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

余额充值