java学习5---多线程

1、线程简介

在这里插入图片描述

2、线程实现(重点)

2.1、线程创建:

2.1.1、Thread class(继承Thread类)

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

//创建线程方式一:继承Thread类,重写run()方法,调用start开启线程
public class testthread extends Thread{
    @Override
    public void run() {
        for(int i=0;i<200;i++) {
            System.out.println("我在学习多线程"+i);
        }
    }

    public static void main(String[] args) {
        testthread testthread1 = new testthread();
        testthread1.start();

        for(int i=0;i<1000;i++) {
            System.out.println("我在学习kuangstudy的java课程"+i);
        }
    }
}

2.1.2、Runnable接口(常用)

//创建线程方式二:实现runable接口,重写run()方法,执行线程需要丢入runable接口
public class testthread implements Runnable{
    @Override
    public void run() {
        for(int i=0;i<200;i++) {
            System.out.println("我在学习多线程"+i);
        }
    }

    public static void main(String[] args) {
        //创建runable接口的实现类对象
        testthread testthread1 = new testthread();

        //创建线程对象,通过线程对象开启线程
        //Thread thread = new Thread(testthread1);
        //thread.start();

        new Thread(testthread1).start();

        for(int i=0;i<1000;i++) {
            System.out.println("我在学习kuangstudy的java课程"+i);
        }
    }
}

//Runable:同一个对象被多个线程使用
public class testthread implements Runnable{

    private int tickets = 10;

    @Override
    public void run() {
        while(true) {
            if (tickets <= 0) {
                break;
            }
            System.out.println(Thread.currentThread().getName()+"-->拿到了第"+tickets--+"张票");
        }
    }

    public static void main(String[] args) {
        //创建runable接口的实现类对象
        testthread ticket = new testthread();

        //创建线程对象,通过线程对象开启线程
        //Thread thread = new Thread(testthread1);
        //thread.start();

        new Thread(ticket,"小明").start();
        new Thread(ticket,"老师").start();
        new Thread(ticket,"黄牛党").start();
    }
}

2.1.3、Callable接口(了解即可)

//1实现callable接口,需要返回值类型;
//2.重写call方法,需要抛出异常
//3.创建目标对象
//4.创建执行服务:
ExecutorService ser = Executors.newFixedThreadPool(1);
//5.提交执行:
Future<Boolean> result1 = ser.submit(t1);
//6.获取结果:
boolean r1 = result1.get();
//7.关闭服务:

ser.shutdownNow();

小结
1.继承Thread类:

  • 子类继承Thread类具备多线程能力;
  • 启动线程:子类对象.start();
  • 不建议使用:避免oop单继承局限性;

2.实现runable接口;

  • 实现接口Runable接口具备多线程能力;
  • 启动对象:传入目标对象+Thread对象.start();
  • 推荐使用:避免单继承局限性,灵活方便,方便同一个对象被多个线程使用;

3.Callable接口(了解即可)

2.2、静态代理模式

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

好处:

  • 真实对象专注于做自己的事;
  • 代理对象可以做真实对象做不了的事;
public class staticproxy {
    public static void main(String[] args) {
        //你要结婚,你是目标
        YOU you = new YOU();
        //把你丢给婚庆公司
        WeddingHelp weddingHelp = new WeddingHelp(you);
        //婚庆公司帮助你结婚
        weddingHelp.HappyMarry();
        
        //以上可归为这一句
        //new WeddingHelp(new YOU()).HappyMarry();
    }
}

interface Marry{
    void HappyMarry();
}

//真实角色
class YOU implements Marry{
    @Override
    public void HappyMarry() {
        System.out.println("你要结婚了,很开心!");
    }
}

//代理角色,给你结婚提供帮助
class WeddingHelp implements Marry{

    private Marry project;

    public WeddingHelp(Marry project){
        this.project=project;
    }

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

    private void before(){
        System.out.println("结婚前,布置婚礼现场");
    }
    private void after(){
        System.out.println("结婚后,收份子钱");
    }
}

2.3、Lamda表达式在这里插入图片描述

1.为什么要用lamda表达式?

  • 避免匿名内部类定义过多
  • 使代码看起来更简洁
  • 去掉了一堆没有意义的代码,只留下核心的逻辑

2.Functional Interface(函数式接口)是lamda表达式的关键所在

  • 任何接口,如果只包含唯一一个抽象方法,那它就是函数式接口
    在这里插入图片描述
  • 对于函数式接口,我们可以通过lamda表达式创建该接口的对象
public class TestLamda {
    public static void main(String[] args) {
        ILike like =new Like();
        like.like(520);
    }
}

interface ILike{
    void like(int a);
}

class Like implements ILike{
    @Override
    public void like(int a) {
        System.out.println("我喜欢-->"+a);
    }
}

2.静态内部类:

public class TestLamda {
    static class Like implements ILike{
        @Override
        public void like(int a) {
            System.out.println("我喜欢-->"+a);
        }
    }

    public static void main(String[] args) {
        ILike like =new Like();
        like.like(520);
    }
}

interface ILike{
    void like(int a);
}

3.局部内部类:

public class TestLamda {
    public static void main(String[] args) {
        class Like implements ILike{
            @Override
            public void like(int a) {
                System.out.println("我喜欢-->"+a);
            }
        }     
        ILike like =new Like();
        like.like(520);
    }
}

interface ILike{
    void like(int a);
}

4.lamda表达式:

public class TestLamda {

    public static void main(String[] args) {
        ILike like =(int a)->{
            System.out.println("我喜欢-->"+a);
        };

        like.like(520);
    }
}
interface ILike{
    void like(int a);
}

5.lamda表达式简化:
注意:

  • lamda表达式只有一行代码的情况下才能简化为一行,如果有多行,必须用代码块包裹,如花括号;
  • 前提是接口必须为函数式接口;
  • 多个参数也可以去掉参数类型,要去掉必须全部去掉,且必须加上括号;
public class TestLamda {

    public static void main(String[] args) {
        ILike like =(int a)->{
            System.out.println("我喜欢-->"+a);
        };
        //简化1:去变量名
        like = (a) -> {
            System.out.println("我喜欢-->" + a);
        };
        //简化2:去括号
        like = a -> {
            System.out.println("我喜欢-->" + a);
        };
        //简化3:去花括号
        like = a -> System.out.println("我喜欢-->" + a;
        
        like.like(520);
    }
}

interface ILike{
    void like(int a);
}

3、线程状态

状态:
在这里插入图片描述
方法:
在这里插入图片描述

3.1、线程停止 Flag

  • 建议线程正常停止—利用次数,不建议死循环
  • 建议使用标志位—设置一个标志位
  • 不要使用stop和destory等jdk不建议使用的方法
    在这里插入图片描述

3.2线程休眠 Sleep
在这里插入图片描述

3、线程礼让 Yield
4.线程强制执行 Join
5.观测线程状态 State
6.线程优先级
7.守护线程 Daemon

线程同步(重点)

  1. 同步方法和同步块
  2. 死锁

3.lock锁:

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

    public void main(){
        try{
            lock.lock();//加锁
            /*
            需要保证线程体安全的代码
             */
        }finally {
            lock.unlock();//解锁
        }
    }
}

Synchronized和Lock的对比:
在这里插入图片描述

线程通信问题

1、线程协作(生产者消费者模式)

1.1 管程法
1.2信号灯法

2.线程池

在这里插入图片描述

高级线程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值