多线程基础

文章目录

  • 线程简介以及相关概念
    • 线程
    • 进程
    • 多线程
    • 普通方法调用和多线程
    • Process与Thread
    • 核心概念
  • 线程创建
    • Thread
  • 线程实现
    • 试下runnable接口
    • 继承和实现的区别
    • 案例:龟兔赛跑
    • 实现Callable接口
  • 线程静态代理
    • 静态代理
  • lamda表达式
    • 总结
  • 线程状态
    • 线程方法
      • 停止线程
      • 线程休眠
      • 线程礼让
      • 线程强制执行
      • 线程状态观测
    • 线程优先级
    • 守护线程
  • 线程同步
    • 并发
    • 队列和锁
  • 同步方法与同步块
    • 同步方法
      • 同步方法弊端
    • 同步块
    • 死锁
      • 死锁避免方法
    • Lock锁
    • synchornized和lock对比
  • 线程通信和协作
    • 生产者和消费者问题
    • 线程之间通信问题
    • 解决方式1
    • 解决方式2
  • 线程池

线程简介以及相关概念

线程

进程

一个进程可以有多个线程,如视频中同时听声音,看图像,看弹幕等等
多线程基础_第1张图片

多线程

普通方法调用和多线程

多线程基础_第2张图片

Process与Thread

多线程基础_第3张图片

核心概念

多线程基础_第4张图片

线程创建

多线程基础_第5张图片

Thread

多线程基础_第6张图片

多线程基础_第7张图片

线程实现

试下runnable接口

多线程基础_第8张图片

/**
 * @Author: ldl
 * @Date: 2020/4/13 20:34
 * @Email: [email protected]
 * @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("我在学习多线程");
            
        }
    }
}

继承和实现的区别

多线程基础_第9张图片

案例:龟兔赛跑

多线程基础_第10张图片

/**
 * @Author: ldl
 * @Date: 2020/4/13 21:09
 * @Email: [email protected]
 * @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接口

多线程基础_第11张图片

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


    /**
     * 网络图片地址
     */
    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 result1 = ser.submit(t1);
        Future result2 = ser.submit(t2);
        Future result3 = ser.submit(t3);
        //获取结果
        Boolean r1 = result1.get();
        Boolean r2 = result2.get();
        Boolean r3 = result3.get();
        //关闭服务
        ser.shutdown();


    }

}

线程静态代理

静态代理

多线程基础_第12张图片

/**
 * @Author: ldl
 * @Date: 2020/4/13 22:16
 * @Email: [email protected]
 * @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表达式

多线程基础_第13张图片
多线程基础_第14张图片
多线程基础_第15张图片

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) {

    }
}

总结

在这里插入图片描述

线程状态

多线程基础_第16张图片
多线程基础_第17张图片

线程方法

多线程基础_第18张图片

停止线程

多线程基础_第19张图片

线程休眠

多线程基础_第20张图片

线程礼让

多线程基础_第21张图片
多线程基础_第22张图片

线程强制执行

多线程基础_第23张图片

线程状态观测

多线程基础_第24张图片

线程优先级

多线程基础_第25张图片

守护线程

多线程基础_第26张图片

线程同步

多个线程操作同一个资源

并发

多线程基础_第27张图片
多线程基础_第28张图片

队列和锁

多线程基础_第29张图片

同步方法与同步块

同步方法

多线程基础_第30张图片

同步方法弊端

多线程基础_第31张图片

同步块

多线程基础_第32张图片

死锁

多线程基础_第33张图片

死锁避免方法

多线程基础_第34张图片

Lock锁

多线程基础_第35张图片
多线程基础_第36张图片

synchornized和lock对比

多线程基础_第37张图片

线程通信和协作

生产者和消费者问题

多线程基础_第38张图片
多线程基础_第39张图片

线程之间通信问题

多线程基础_第40张图片

解决方式1

多线程基础_第41张图片

/**
 * @Author: ldl
 * @Date: 2020/4/17 15:51
 * @Email: [email protected]
 * @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

多线程基础_第42张图片

/**
 * @Author: ldl
 * @Date: 2020/4/17 16:05
 * @Email: [email protected]
 * @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;
    }
}

线程池

多线程基础_第43张图片
多线程基础_第44张图片

你可能感兴趣的:(并发基础,多线程,多线程,java)