多线程基础

线程简介以及相关概念

线程

进程

一个进程可以有多个线程,如视频中同时听声音,看图像,看弹幕等等
在这里插入图片描述

多线程

普通方法调用和多线程

在这里插入图片描述

Process与Thread

在这里插入图片描述

核心概念

在这里插入图片描述

线程创建

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-evOQGwGV-1587623679871)(55B07CB9BA654370847B9C82D99281D8)]

Thread

在这里插入图片描述

在这里插入图片描述

线程实现

试下runnable接口

/**
 * @Author: ldl
 * @Date: 2020/4/13 20:34
 * @Email: 18234780819@163.com
 * @Desc: 实现runnable接口,重写run方法,执行线程需要丢人接口实现类  调用star
 */
public class TestThread3 implements Runnable{

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

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

        //创建线程对象,通过线程对象来开启线程  代理
        new Thread(testThread3).start();
        
        for (int i = 0; i < 1000; i++) {
            System.out.println("我在学习多线程");
            
        }
    }
}

继承和实现的区别

在这里插入图片描述

案例:龟兔赛跑

在这里插入图片描述

/**
 * @Author: ldl
 * @Date: 2020/4/13 21:09
 * @Email: 18234780819@163.com
 * @Desc: 模拟龟兔赛跑
 */
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(200);
                } 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();

    }

}

实现Callable接口

在这里插入图片描述

/**
 * @Author: ldl
 * @Date: 2020/4/13 21:25
 * @Email: 18234780819@163.com
 * @Desc:  实现callable接口来来创建线程
 *         优势:可以定义返回值
 *              可以抛出异常
 */
@Slf4j
public class TestCallable implements Callable<Boolean> {


    /**
     * 网络图片地址
     */
    private String url;
    /**
     * 保存的文件名
     */
    private String name;

    public TestCallable(String url,String name){
        this.url = url;
        this.name = name;
    }

    @Override
    public Boolean call() {
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url,name);
        log.info("下载了文件名为:"+name+"");
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestCallable t1 = new TestCallable("https://i0.hdslb.com/bfs/sycp/creative_img/202004/debdfee6d89cca6b711b89a5e18c33d4.jpg","1.jpg");
        TestCallable t2 = new TestCallable("https://i0.hdslb.com/bfs/sycp/creative_img/202004/debdfee6d89cca6b711b89a5e18c33d4.jpg","2.jpg");
        TestCallable t3 = new TestCallable("https://i0.hdslb.com/bfs/sycp/creative_img/202004/debdfee6d89cca6b711b89a5e18c33d4.jpg","3.jpg");

        //创建程序
        ExecutorService ser = Executors.newFixedThreadPool(1);
        //提交执行
        Future<Boolean> result1 = ser.submit(t1);
        Future<Boolean> result2 = ser.submit(t2);
        Future<Boolean> result3 = ser.submit(t3);
        //获取结果
        Boolean r1 = result1.get();
        Boolean r2 = result2.get();
        Boolean r3 = result3.get();
        //关闭服务
        ser.shutdown();


    }

}

线程静态代理

静态代理

在这里插入图片描述

/**
 * @Author: ldl
 * @Date: 2020/4/13 22:16
 * @Email: 18234780819@163.com
 * @Desc:  静态代理模式总结
 *           真实对象和代理对象都要实现同一个接口
 *           代理对象要代理真实角色
 *         好处:
 *           代理对象可以做很多真实对象做不了的事情
 *           真实对象专注做自己的事情
 */
public class StaticProxy {

    public static void main(String[] args) {
        new WeddingCompany(new You()).happyMarry();

        //在线程里  Thread代理真实Runnable  都实现了runnable接口
        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("结婚之后收尾款");
    }
}

lamda表达式

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

public class TestLambda {

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

        like = (a)->{
            System.out.println("123123"+a);
        };

        like = a->{
            System.out.println("123123"+a);
        };

        like = a-> System.out.println("123123"+a);
        like.lambda(123);
    }

}

/**
 * 函数式接口
 *
 */
interface ILike{
    void lambda(int a);
}

class Like implements ILike{

    @Override
    public void lambda(int a) {

    }
}

总结

在这里插入图片描述

线程状态

在这里插入图片描述
在这里插入图片描述

线程方法

在这里插入图片描述

停止线程

在这里插入图片描述

线程休眠

在这里插入图片描述

线程礼让

在这里插入图片描述
在这里插入图片描述

线程强制执行

在这里插入图片描述

线程状态观测

在这里插入图片描述

线程优先级

在这里插入图片描述

守护线程

在这里插入图片描述

线程同步

多个线程操作同一个资源

并发

在这里插入图片描述
在这里插入图片描述

队列和锁

在这里插入图片描述

同步方法与同步块

同步方法

在这里插入图片描述

同步方法弊端

在这里插入图片描述

同步块

在这里插入图片描述

死锁

在这里插入图片描述

死锁避免方法

在这里插入图片描述

Lock锁

在这里插入图片描述
在这里插入图片描述

synchornized和lock对比

在这里插入图片描述

线程通信和协作

生产者和消费者问题

在这里插入图片描述
在这里插入图片描述

线程之间通信问题

在这里插入图片描述

解决方式1

在这里插入图片描述

/**
 * @Author: ldl
 * @Date: 2020/4/17 15:51
 * @Email: 18234780819@163.com
 * @Desc: 测试生产者消费者模型  利用缓冲区解决:管程法
 */
public class TestPC {

    public static void main(String[] args) {
        SynContainer container = new SynContainer();
        new Productor(container).start();
        new Consumer(container).start();
    }

}

class Productor extends Thread{

    SynContainer container;

    public Productor(SynContainer container){
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            container.push(new Chicken(i));
            System.out.println("生产了"+i+"只鸡");
        }
    }

}

class Consumer extends Thread{

    SynContainer container;

    public Consumer(SynContainer container){
        this.container = container;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("消费了"+container.pop().id+"只鸡");
        }
    }
}

class Chicken{
    int id;

    public Chicken(int id) {
        this.id = id;
    }
}

//缓冲区
class SynContainer{
    //容器大小
    Chicken[] chickens = new Chicken[10];

    int count = 0;

    //生产者放入产品
    public synchronized void push(Chicken chicken){
        if (count == chickens.length){
            //通知消费者消费,生产者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        chickens[count] = chicken;
        count++;
        //通知消费者消费
        this.notifyAll();
    }
    //消费者消费产品
    public synchronized Chicken pop(){
        if (count == 0){
            //等待生产
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        //消费
        count--;
       Chicken chicken =  chickens[count];

       //通知生产
        this.notifyAll();
        return chicken;
    }

}

解决方式2

在这里插入图片描述

/**
 * @Author: ldl
 * @Date: 2020/4/17 16:05
 * @Email: 18234780819@163.com
 * @Desc: 测试生产者消费者问题2 信号灯法,标志位解决
 */
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){
                this.tv.player("xx");
            }else{
                this.tv.player("xx2");
            }
        }
    }
}

//消费者
class Watcher extends Thread{
    TV tv;
    public Watcher(TV tv){
        this.tv = tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            tv.watch();
        }
    }
}

//产品
class TV{
    String voice;
    boolean flag = true;

    public synchronized void player(String voice){
        if (!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("演员表演了"+voice);
        //通知观众
        this.notifyAll();
        this.voice = voice;
        this.flag = !this.flag;
    }

    public synchronized void watch(){
        if (flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        System.out.println("观众观看"+voice);
        //通知演员
        this.notifyAll();
        this.flag = !this.flag;
    }
}

线程池

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值