Java学习_Day 01(学习内容:狂神说多线程)

P3 继承Thread类

package com.hu.thread;
// 创建线程方式一:继承Thread类,重写run方法,调用start开启线程
// 线程开启不一定立即执行,由CPU调度执行
public class TestThread1 extends Thread{
    @Override
    public void run() {
        // run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("看代码" + i);
        }
        super.run();
    }

    public static void main(String[] args) {
        // main线程

        // 创建一个线程对象
        TestThread1 testThread1 = new TestThread1();

        // 开启线程
        testThread1.start();

        for (int i = 0; i < 20; i++) {
            System.out.println("我在学习多线程" + i);
        }
    }
}

P4 网图下载

package com.hu.thread;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;

// 练习Thread实现多线程下载器
public class TestThread2 extends Thread{
    private String url;
    private String name;

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

    @Override
    public void run() {
        WebDownloader webDownloader = new WebDownloader();
        webDownloader.downloader(url, name);
        System.out.println("下载的文件名为" + name);
    }

    public static void main(String[] args) {
        TestThread2 t1 = new TestThread2("http:xxx", "1.jpg");
        TestThread2 t2 = new TestThread2("http:xxx", "1.jpg");
        TestThread2 t3 = new TestThread2("http:xxx", "1.jpg");
        t1.start();
        t2.start();
        t3.start();
    }

}

// 下载器
class WebDownloader {
    public void downloader(String url, String name) {
        try {
            FileUtils.copyURLToFile(new URL(url), new File(name));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO异常");
        }
    }
}

P5 实现Runnable接口

package com.hu.thread;

// 创建线程方式2:实现runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法
public class TestThread3 implements Runnable{
    @Override
    public void run() {
        // run方法线程体
        for (int i = 0; i < 20; i++) {
            System.out.println("看代码" + i);
        }
    }

    public static void main(String[] args) {
        // 创建runnable接口的实现类对象
        TestThread3 testThread3 = new TestThread3();
        // 创建线程对象,通过线程对象来开启我们的线程代理
        Thread thread = new Thread(testThread3);
        thread.start();

        for (int i = 0; i < 20; i++) {
            System.out.println("我在学习多线程" + i);
        }
    }
}

P6 初识并发问题

package com.hu.thread;

// 多线程操作同一个对象
// 多线程操作同一个对象可能出现线程不安全问题,并发紊乱
public class TestThread4 implements Runnable{
    // 票数
    private int ticketNums = 18;
    @Override
    public void run() {
        while (true){
            if (ticketNums <= 0){
                break;
            }
            System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketNums-- + "票");
        }
    }

    public static void main(String[] args) {
        TestThread4 testThread4 = new TestThread4();
        new Thread(testThread4, "小明").start();
        new Thread(testThread4, "黄牛").start();
        new Thread(testThread4, "小红").start();
    }
}

P7 龟兔赛跑

package com.hu.thread;
// 模拟龟兔赛跑
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("兔子")){
                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();
    }
}

P8 callable接口(线程池)

P9 静态代理模式

package com.hu.thread;
/*
代理模式
真实对象和代理模式都要实现同一个接口
代理对象要代理真实角色
好处
    代理对象可以做很多真实对象做不了的事情
    真实对象专注做自己的事情
 */

public class StaticProxy {
    public static void main(String[] args) {
        
        WeddingCompany weddingCompany = new WeddingCompany(new You());
        weddingCompany.HappyMarry();
    }
}


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 after(){
        System.out.println("结婚之后收尾款");
    }
    private void before(){
        System.out.println("结婚之前,布置现场");
    }
}

P10 Lamda表达式

package com.hu.thread;

public class Testlambda1 {
    // 3. 静态内部类
    static class Like2 implements ILike{
        @Override
        public void lambda() {
            System.out.println("I like lambda2");
        }
    }
    public static void main(String[] args) {
        ILike like = new Like();
        like.lambda();
        like = new Like2();
        like.lambda();
        // 4. 局部内部类
        class Like3 implements ILike{
            @Override
            public void lambda() {
                System.out.println("I like lambda3");
            }
        }
        like = new Like3();
        like.lambda();
        // 5. 匿名内部类, 没有类的名称,必须借助接口或者父类
        like = new ILike(){
            @Override
            public void lambda() {
                System.out.println("I like lambda4");
            }
        };
        like.lambda();
        // 6. 用lambda简化
        like = ()->{
            System.out.println("I like lambda5");
        };
        like.lambda();

    }
}

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

// 2. 定义一个实现类
class Like implements ILike{
    @Override
    public void lambda() {
        System.out.println("I like lambda");
    }
}
package com.hu.thread;

public class TestLambda2 {
//    static class Love implements Ilove{
//        @Override
//        public void love(int a) {
//            System.out.println("I love u>>"+a);
//        }
//    }
    public static void main(String[] args) {
//        class Love implements Ilove{
//        @Override
//        public void love(int a) {
//            System.out.println("I love u>>"+a);
//            }
//        }
        Ilove love = (int a)-> {
            System.out.println("I love u>>"+a);
        };
        love.love(2);
        // lambda简化1:参数类型
        love = (a)-> {
            System.out.println("I love u>>"+a);
        };
        love.love(2);
        // lambda简化2:简化括号
        love = a-> {
            System.out.println("I love u>>"+a);
        };
        love.love(2);
        // lambda简化3:简化大括号
        love = a-> System.out.println("I love u>>"+a);
        love.love(2);
        // 总结:接口里只能有一个方法,必须是函数接口
        //      lambda表达式在一行代码情况下可以简化大括号,其他必须用代码块包裹
        //      多个参数也可以去掉参数类型,要去掉都去掉,但必须要加上括号
    }
}

interface Ilove{
    void love(int a);
}

//class Love implements Ilove{
//    @Override
//    public void love(int a) {
//        System.out.println("I love u>>"+a);
//    }
//}

P11 线程停止

package com.hu.thread;
/*
测试stop
建议线程正常停止,利用循环次数
建议使用标志位
不要使用stop\destroy等过时方法
 */
public class TestStop implements Runnable{
    // 设置一个标志位
    private boolean flag = true;

    @Override
    public void run() {
        int i = 0;
        while (flag){
            System.out.println("run...Thread" + i++);
        }
    }
    // 设置一个公开的方法停止线程,转换标志位
    public void stop(){
        this.flag = false;
    }
    public static void main(String[] args) {
        TestStop testStop = new TestStop();
        new Thread(testStop).start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("main" + i);
            if (i == 900){
                testStop.stop();
                System.out.println("线程停止");
            }
        }
    }
}

P12 线程休眠

package com.hu.thread;
// 模拟网络延时: 放大问题的发生性
public class TestSleep implements Runnable{
    // 票数
    private int ticketNums = 18;
    @Override
    public void run() {
        while (true){
            if (ticketNums <= 0){
                break;
            }
            // 模拟延时
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketNums-- + "票");
        }
    }

    public static void main(String[] args) {
        TestThread4 testThread4 = new TestThread4();
        new Thread(testThread4, "小明").start();
        new Thread(testThread4, "黄牛").start();
        new Thread(testThread4, "小红").start();
    }
}
package com.hu.thread;

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

// 模拟倒计时
public class TestSleep2 {
    public static void main(String[] args) {
//        try {
//            tenDown();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        // 打印当前系统时间
        Date startTime = new Date(System.currentTimeMillis());
        while (true) {
            try {
                Thread.sleep(1000);
                System.out.println(new SimpleDateFormat("HH:mm:ss").format(startTime));
                startTime = new Date(System.currentTimeMillis());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void tenDown() throws InterruptedException {
        int num = 10;
        while (true){
            Thread.sleep(1000);
            System.out.println(num--);
            if (num <= 0){
                break;
            }
        }
    }
}

P13 线程礼让

package com.hu.thread;
// 测试礼让线程
// 礼让不一定成功,看CPU心情
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() + "线程停止执行");
    }
}

P14 线程强制执行

package com.hu.thread;
// 测试join方法
public class TestJoin implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("线程VIP来了" + i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TestJoin testJoin = new TestJoin();
        Thread thread = new Thread(testJoin);
        thread.start();
        // 主线程
        for (int i = 0; i < 1000; i++) {
            if (i == 200){
                thread.join(); // 插队
            }
            System.out.println("main" + i);
        }
    }
}

P14 线程强制执行

package com.hu.thread;
// 测试join方法
public class TestJoin implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("线程VIP来了" + i);
        }
    }

    public static void main(String[] args) throws InterruptedException {
        TestJoin testJoin = new TestJoin();
        Thread thread = new Thread(testJoin);
        thread.start();
        // 主线程
        for (int i = 0; i < 1000; i++) {
            if (i == 200){
                thread.join(); // 插队
            }
            System.out.println("main" + i);
        }
    }
}

P15 观测线程状态

package com.hu.thread;
// 观察线程状态
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) {
                    e.printStackTrace();
                }
            }
            System.out.println("");
        });

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

        thread.start();
        System.out.println(thread.getState());

        while (state != Thread.State.TERMINATED){
            Thread.sleep(100);
            state = thread.getState();
            System.out.println(state);
        }
    }


}

P16 线程的优先级

package com.hu.thread;
// 测试线程的优先级
public class TestPriority extends Thread {
    public static void main(String[] args) {
        // 主线程优先级
        System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
        MyPriority myPriority = new MyPriority();
        Thread thread1 = new Thread(myPriority);
        Thread thread2 = new Thread(myPriority);
        Thread thread3 = new Thread(myPriority);
        Thread thread4 = new Thread(myPriority);
        Thread thread5 = new Thread(myPriority);
        // 设置优先级,再启动
        thread1.start();

        thread2.setPriority(1);
        thread2.start();

        thread3.setPriority(4);
        thread3.start();

        thread4.setPriority(Thread.MAX_PRIORITY);
        thread4.start();

//        thread5.setPriority(-1);
//        thread5.start();
    }
}


class MyPriority implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority());
    }
}

P17 守护线程

package com.hu.thread;
// 测试守护线程

public class TestDaemon {
    public static void main(String[] args) {
        God god = new God();
        You1 you1 = new You1();
        Thread thread = new Thread(god); // 默认false表示用户线程,正常的线程都是用户线程
        thread.setDaemon(true);
        thread.start(); // 上帝守护线程启动
        new Thread(you1).start();
    }
    
}
class God implements Runnable{
    @Override
    public void run() {
        while (true){
            System.out.println("上帝保佑着你");
        }
    }
}


class You1 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 365000; i++) {
            System.out.println("你一生都开心的活着");
        }
        System.out.println("goodbye, world!");
    }
}

P18 线程同步机制

P19 三大不安全案例

package com.hu.thread;
// 不安全的取钱
// 两个人去银行取钱
public class UnsafeBank {
    public static void main(String[] args) {
        Account account = new Account(100, "结婚基金");
        Drawing Li =  new Drawing(account, 50, "小李");
        Drawing Wang = new Drawing(account, 100, "小王");
//        Drawing Gi = new Drawing(account, 50, "小G");
        Li.start();
        Wang.start();
    }
}

// 账户
class Account{
    int money;
    String name;

    public Account(int money, String name){
        this.money = money;
        this.name = name;
    }
}

// 银行 模拟取款
class Drawing extends Thread{
    Account account;
    int drawingMoney;
    int nowMoney;
    public Drawing(Account account, int drawingMoney, String name){
        super(name);
        this.account = account;
        this.drawingMoney = drawingMoney;
    }
    // 取钱

    @Override
    public void run() {
        // 判断有没有钱
        if (account.money - drawingMoney < 0){
            System.out.println(Thread.currentThread().getName() + "余额不足");
            return;
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        account.money = account.money - drawingMoney;
        nowMoney = nowMoney + drawingMoney;
        System.out.println(account.name + "余额为" + account.money);
        System.out.println(this.getName() + "手里的钱" + nowMoney);
    }
}
package com.hu.thread;
// 不安全的买票,线程不安全
public class UnsafeBuyTicket {
    public static void main(String[] args) {
        BuyTicket station = new BuyTicket();
        new Thread(station, "小李").start();
        new Thread(station, "小王").start();
        new Thread(station, "黄牛").start();

    }
}



class BuyTicket implements Runnable {
    // 票
    private int ticketNums = 10;
    boolean flag = true;

    @Override
    public void run() {
        while (flag){
            try {
                buy();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private void buy() throws InterruptedException {
        // 判断是否有票
        if (ticketNums <= 0){
            flag = false;
            return;
        }
        // 模拟延迟
        Thread.sleep(100);

        // 买票
        System.out.println(Thread.currentThread().getName() + "拿到" + ticketNums--);
    }
}
package com.hu.thread;

import java.util.ArrayList;

public class UnsafeList {
    public static void main(String[] args) throws InterruptedException {
        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            new Thread(()->{
                list.add(Thread.currentThread().getName());
            }).start();
        }
        Thread.sleep(3000);
        System.out.println(list.size());
    }
}

P20 同步方法及同步代码块

package com.hu.thread;
// 不安全的取钱
// 两个人去银行取钱
public class UnsafeBank {
    public static void main(String[] args) {
        Account account = new Account(100, "结婚基金");
        Drawing Li =  new Drawing(account, 50, "小李");
        Drawing Wang = new Drawing(account, 100, "小王");
//        Drawing Gi = new Drawing(account, 50, "小G");
        Li.start();
        Wang.start();
    }
}

// 账户
class Account{
    int money;
    String name;

    public Account(int money, String name){
        this.money = money;
        this.name = name;
    }
}

// 银行 模拟取款
class Drawing extends Thread{
    Account account;
    int drawingMoney;
    int nowMoney;
    public Drawing(Account account, int drawingMoney, String name){
        super(name);
        this.account = account;
        this.drawingMoney = drawingMoney;
    }
    // 取钱
    // synchronized 默认锁的是this
    @Override
    public void run() {
        synchronized (account){
            // 判断有没有钱
            if (account.money - drawingMoney < 0){
                System.out.println(Thread.currentThread().getName() + "余额不足");
                return;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            account.money = account.money - drawingMoney;
            nowMoney = nowMoney + drawingMoney;
            System.out.println(account.name + "余额为" + account.money);
            System.out.println(this.getName() + "手里的钱" + nowMoney);
        }
    }
}
package com.hu.thread;
// 不安全的买票,线程不安全
public class UnsafeBuyTicket {
    public static void main(String[] args) {
        BuyTicket station = new BuyTicket();
        new Thread(station, "小李").start();
        new Thread(station, "小王").start();
        new Thread(station, "黄牛").start();

    }
}



class BuyTicket implements Runnable {
    // 票
    private int ticketNums = 10;
    boolean flag = true;

    @Override
    public void run() {
        while (flag){
            try {
                buy();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    private synchronized void buy() throws InterruptedException {
        // 判断是否有票
        if (ticketNums <= 0){
            flag = false;
            return;
        }
        // 模拟延迟
        Thread.sleep(100);

        // 买票
        System.out.println(Thread.currentThread().getName() + "拿到" + ticketNums--);
    }
}
package com.hu.thread;

import java.util.ArrayList;

public class UnsafeList {
    public static void main(String[] args) throws InterruptedException {
        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            new Thread(()->{
                synchronized (list){
                    list.add(Thread.currentThread().getName());
                }
            }).start();
        }
        Thread.sleep(3000);
        System.out.println(list.size());
    }
}

P21 CopyOnWriteArrayList

package com.hu.thread;

import java.util.concurrent.CopyOnWriteArrayList;

// 测试JUC安全类型的集合
public class TestJUC {
    public static void main(String[] args) throws InterruptedException {
        CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<String>();
        for (int i = 0; i < 10000; i++) {
            new Thread(()->{
                list.add(Thread.currentThread().getName());
            }).start();
        }
        Thread.sleep(3000);
        System.out.println(list.size());
    }
}

P22 死锁

package com.hu.thread;
// 死锁:多个线程需要对方的资源就形成死锁
public class DeadLock {
    public static void main(String[] args) {
        Makeup g1 = new Makeup(0, "小红");
        Makeup g2 = new Makeup(1, "小白");
        g1.start();
        g2.start();
    }
}


class Lipstick{

}

class Mirror{

}

class Makeup extends Thread{
    // 需要的资源只有一份
    static Lipstick lipstick = new Lipstick();
    static Mirror mirror = new Mirror();
    int choice;
    String girlName;

    Makeup(int choice, String girlName){
        this.choice = choice;
        this.girlName = girlName;
    }

    @Override
    public void run() {
//        super.run();
        try {
            makeup();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private void makeup() throws InterruptedException {
        if (choice == 0){
            synchronized (lipstick){ //口红的锁
                System.out.println(this.girlName + "获得口红的锁");
                Thread.sleep(1000);
//                synchronized (mirror){ //一秒钟后想获得镜子
//                    System.out.println(this.girlName + "获得镜子的锁");
//                }
            }
            synchronized (mirror){ //一秒钟后想获得镜子
                System.out.println(this.girlName + "获得镜子的锁");
            }
        } else {
            synchronized (mirror){
                System.out.println(this.girlName + "获得镜子的锁");
                Thread.sleep(2000);
//                synchronized (lipstick){
//                    System.out.println(this.girlName + "获得口红的锁");
//                }
            }
            synchronized (lipstick){
                System.out.println(this.girlName + "获得口红的锁");
            }
        }
    }
}

P23 lock锁

package com.hu.thread;

import java.util.concurrent.locks.ReentrantLock;

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 ticketNums = 10;
    // 定义lock锁
    private final ReentrantLock lock = new ReentrantLock();

    @Override
    public void run() {
        while (true){
            try {
                lock.lock(); //加锁
                if (ticketNums>0){
                    try {
                        Thread.sleep(1000);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(ticketNums--);
                }else {
                    break;
                }
            }finally {
                lock.unlock();
            }


        }
    }
}

P25 管程法

package com.hu.thread;
// 生产者消费者模型-->利用缓冲区解决:管程法
// 生产、消费、产品、缓冲区
public class TestPC {
    public static void main(String[] args) {
        SynContainer container = new SynContainer();
        new Producer(container).start();
        new Consumer(container).start();
    }
}

// 生产者
class Producer extends Thread{
    SynContainer container;
    public Producer(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;
    }
}

P26 信号灯法

package com.hu.thread;
// 信号灯法,标志位解决
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.play("快乐大本营播放");
            } else {
                this.tv.play("抖音记录美好生活");
            }
        }
    }
}
// 消费者->观众
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 {
    // 演员表演,观众等待 T
    // 观众观看,演员等待 F
    String voice; // 表演的节目
    boolean flag = true;

    // 表演
    public synchronized void play(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;
    }
}

P27 线程池

package com.hu.thread;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TestPool {
    public static void main(String[] args) {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        executorService.execute(new MyThread());
        executorService.execute(new MyThread());
        executorService.execute(new MyThread());
        executorService.execute(new MyThread());
    }
}

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

你可能感兴趣的:(JAVA学习,java,学习,代理模式)