Java进阶04多线程

Java进阶04多线程

概述

image
image
image
image
image
image
image

线程创建

image

Thread类

image

package com.mingmao.multithreading.thread;

//创建线程方法一,继承Thread类,重写run()方法,调用start开启线程
public class TestThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
            System.out.println("这是run线程,我在写代码----"+i);
        }
    }

    public static void main(String[] args) {
        TestThread testThread=new TestThread();
        //testThread.run();//单线程,先执行完run()线程再继续往下执行
        testThread.start(); //两条线程随机交替执行,cpu调度的,每次执行都不一样

        for (int i = 0; i < 20; i++) {
            System.out.println("这是主线程,我在看书-----"+i);
        }
    }
}

练习 多线程下载图片

使用jar包

1.下载jar包
commons.io 下载地址
2.copy jar包到IEDA
image
image
image
image
image
image
image
image

多线程下载图片

package com.mingmao.multithreading.thread;

import org.apache.commons.io.FileUtils;

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

//练习Thread,实现多线程同步下载图片
public class DownloadPictures extends Thread{
    private String url;//网络图片地址
    private String filename;//保存的文件名

    public DownloadPictures(String url,String filename){
        this.url=url;
        this.filename=filename;
    }

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

    public static void main(String[] args) {
        DownloadPictures downloadPictures1=new DownloadPictures("https://img2020.cnblogs.com/blog/2529444/202109/2529444-20210903150234451-1160669624.png","D:\\file\\javatest\\JavaSE\\java进阶\\file\\pic\\1.jpg");
        DownloadPictures downloadPictures2=new DownloadPictures("https://img2020.cnblogs.com/blog/2529444/202109/2529444-20210903150422206-2042991969.png","D:\\file\\javatest\\JavaSE\\java进阶\\file\\pic\\2.jpg");
        DownloadPictures downloadPictures3=new DownloadPictures("https://img2020.cnblogs.com/blog/2529444/202109/2529444-20210903150704087-1931814188.png","D:\\file\\javatest\\JavaSE\\java进阶\\file\\pic\\3.jpg");

        downloadPictures1.start();
        downloadPictures2.start();
        downloadPictures3.start();
    }
}

//下载器
class WebDownloader{
    //下载方法
    public void downloader(String url,String filename){
        try {
            FileUtils.copyURLToFile(new URL(url),new File(filename));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO异常,downloader方法出现问题");
        } finally {
        }
    }
}

Runnable接口

image

package com.mingmao.multithreading.runnable;

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

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

        for (int i = 0; i < 20; i++) {
            System.out.println("这是主线程,我在看书-----"+i);
        }
    }
}

image

初识并发问题

package com.mingmao.multithreading.concurrencyproblem;

//多个线程同时操作同一个对象--买火车票
public class TestConcurrency implements Runnable {
    private int ticketNums=10;

    @Override
    public void run() {
        while (true){
            if(ticketNums<=0){
                break;
            }
            System.out.println(Thread.currentThread().getName()+"拿到了第"+ticketNums--+"张票");
            //延时
            try {
                Thread.sleep(200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
            }

        }
    }

    public static void main(String[] args) {
        TestConcurrency testConcurrency=new TestConcurrency();
        new Thread(testConcurrency,"小明").start();
        new Thread(testConcurrency,"小红").start();
        new Thread(testConcurrency,"小丽").start();
        /*
        小丽拿到了第10张票
        小明拿到了第10张票
        小红拿到了第9张票
        小红拿到了第8张票
        小明拿到了第7张票
        小丽拿到了第6张票
        小明拿到了第5张票
        小红拿到了第3张票
        小丽拿到了第4张票
        小红拿到了第2张票
        小明拿到了第2张票
        小丽拿到了第1张票
         */
        //问题,票拿重复了,多线程操作同一资源,线程不安全,数据紊乱
    }
}

练习 龟兔赛跑

image

package com.mingmao.multithreading.concurrencyproblem;

//模拟龟兔赛跑
public class TortoiseAndRabbitRace implements Runnable{
    private static String winner;

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            //模拟兔子休息 兔子每跑10步休息10ms
            if(Thread.currentThread().getName().equals("兔子")&& i%10==0){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                }
            }

            boolean b=gameOver(i);
            if(b){
                break;
            }else{
                System.out.println(Thread.currentThread().getName()+"跑了"+i+"步");
            }
        }
    }

    //判断是否完成比赛
    private boolean gameOver(int steps){
        if(winner!=null){return true;}
        if(steps==100){
            winner=Thread.currentThread().getName();
            System.out.println("winner is "+winner);
            return true;
        }
        return false;
    }

    public static void main(String[] args) {
        TortoiseAndRabbitRace tortoiseAndRabbitRace=new TortoiseAndRabbitRace();
        new Thread(tortoiseAndRabbitRace,"兔子").start();
        new Thread(tortoiseAndRabbitRace,"乌龟").start();
    }
}

Callable接口

image

package com.mingmao.multithreading.callable;

import org.apache.commons.io.FileUtils;

import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.concurrent.*;

//多线程创建方式三:实现Callable接口 以下载图片为例
public class TestCallable implements Callable {
    private String url;
    private String filename;

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

    @Override
    public Boolean call() throws Exception {
        WebDownloader webDownloader=new WebDownloader();
        webDownloader.downloader(url,filename);
        System.out.println("已下载图片"+filename);
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        TestCallable testCallable1=new TestCallable("https://img2020.cnblogs.com/blog/2529444/202109/2529444-20210903150234451-1160669624.png","D:\\file\\javatest\\JavaSE\\java进阶\\file\\pic\\4.jpg");
        TestCallable testCallable2=new TestCallable("https://img2020.cnblogs.com/blog/2529444/202109/2529444-20210903150422206-2042991969.png","D:\\file\\javatest\\JavaSE\\java进阶\\file\\pic\\5.jpg");
        TestCallable testCallable3=new TestCallable("https://img2020.cnblogs.com/blog/2529444/202109/2529444-20210903150704087-1931814188.png","D:\\file\\javatest\\JavaSE\\java进阶\\file\\pic\\6.jpg");

        //创建执行服务
        ExecutorService executorService= Executors.newFixedThreadPool(3);
        //提交执行
        Future<Boolean> future1=executorService.submit(testCallable1);
        Future<Boolean> future2=executorService.submit(testCallable2);
        Future<Boolean> future3=executorService.submit(testCallable3);
        //获取结果
        boolean b1=future1.get();
        boolean b2=future2.get();
        boolean b3=future3.get();
        //关闭服务
        executorService.shutdownNow();
    }
}

//下载器
class WebDownloader{
    public void downloader(String url,String filrname){
        try {
            FileUtils.copyURLToFile(new URL(url),new File(filrname));
        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("IO异常,downloader方法出现问题");
        } finally {
        }
    }
}

静态代理模式

image

package com.mingmao.multithreading.staticproxy;
/*
静态代理模式:
真实对象和代理对象都要实现同一个接口
代理对象要代理真实角色,传递给代理对象一个参数
代理对象可以做很多真是对象做不了的事情
真是对象就专注做自己的事情
 */
public class TestStaticProxy  {
    public static void main(String[] args) {
        //WeddingCompany weddingCompany=new WeddingCompany(new You());//丢入的是接口Marry的实现类
        //weddingCompany.happyMarry();
        new WeddingCompany(new You()).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("结婚之前,布置现场");
    }
}

Lambda表达式

image
image
image

package com.mingmao.multithreading.lambda;

//推导Lambda表达式
//原来的做法
public class TestLambda {
    public static void main(String[] args) {
        ILike iLike=new Like();
        iLike.lambda();
    }
}

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

//实现类
class Like implements ILike{
    @Override
    public void lambda() {
        System.out.println("I like lambda.");
    }
}
package com.mingmao.multithreading.lambda;

//推导Lambda表达式
//静态内部类
public class TestLambda {
    //静态内部类
   static class Like implements ILike{
        @Override
        public void lambda() {
            System.out.println("I like lambda.");
        }
    }

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

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

//推导Lambda表达式
//局部内部类
public class TestLambda {
    public static void main(String[] args) {
        class Like implements ILike{
            @Override
            public void lambda() {
                System.out.println("I like lambda.");
            }
        }

        ILike iLike=new Like();
        iLike.lambda();
    }
}

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

//推导Lambda表达式
//匿名内部类
public class TestLambda {
    public static void main(String[] args) {
        //匿名内部类,没有类的名称,必须借助接口或者父类
        new ILike(){
            @Override
            public void lambda() {
                System.out.println("I like lambda.");
            }
        }.lambda();
    }
}

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

//推导Lambda表达式
//用lambda简化
public class TestLambda {
    public static void main(String[] args) {
        ILike iLike=() -> {
            System.out.println("I like lambda.");
        };
        iLike.lambda();
    }
}

//定义一个函数式接口
interface ILike{
    void lambda();
}
//带参数的接口
public class TestLambda2 {
    public static void main(String[] args) {
        ILove iLove=(i)->{
            System.out.println("I love you "+i);
        };
        iLove.love(5);
    }
}

interface ILove{
    void love(int i);
}
package com.mingmao.multithreading.lambda;

//带参数的接口
public class TestLambda2 {
    public static void main(String[] args) {
        //只有一行代码可以简化括号,如果有多行代码,必须用代码块包裹
        ILove iLove=i-> System.out.println("I love you "+i);
        iLove.love(5);
    }
}

interface ILove{
    void love(int i);
}

线程状态及常用方法

image
image
image

停止线程stop

image

package com.mingmao.multithreading.commonmethod;

/*
测试stop:
1、建议线程正常停止--利用次数,不建议死循环
2、建议使用标志位--设置一个标志位
3、不要使用stop或者destroy等过时或者JDK不建议使用的方法
 */
public class TestStop implements Runnable{
    private boolean flag=true;

    @Override
    public void run() {
        int i=0;
        while (flag){
            System.out.println("run-----"+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("线程run停止了");
            }
        }
    }
}

线程休眠 sleep

image

package com.mingmao.multithreading.commonmethod;

//模拟网络延时:放大问题的发生性
public class TestSleep implements Runnable {
    private int ticketNums=10;
    private boolean flag=true;

    @Override
    public void run() {
        while (flag){
            if(ticketNums<=0){
                break;
            }
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
            }
            System.out.println(Thread.currentThread().getName()+"抢到了第"+ticketNums--+"张票");
        }
    }

    public void stop(){
        this.flag=false;
    }

    public static void main(String[] args) {
        TestSleep testSleep=new TestSleep();
        new Thread(testSleep,"小明").start();
        new Thread(testSleep,"小红").start();
        new Thread(testSleep,"小丽").start();
    }
}
package com.mingmao.multithreading.commonmethod;

//模拟倒计时
public class TestSleep2{
    private int time=10;

    public void countDown() {
        while (true){
            if(time<0){
                break;
            }
            System.out.println("倒计时:"+time--);
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
            }
        }
    }

    public static void main(String[] args) {
        TestSleep2 testSleep2=new TestSleep2();
        testSleep2.countDown();
    }
}

线程礼让 yield

image

package com.mingmao.multithreading.commonmethod;

//礼让不一定成功,只是让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()+"线程结束");
    }
}

线程强制执行join

image

package com.mingmao.multithreading.commonmethod;

//强行插队
public class TestJoin implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("线程vip来了--"+i);
        }
    }

    public static void main(String[] args) {
        TestJoin testJoin=new TestJoin();
        Thread thread=new Thread(testJoin);
        thread.start();

        for (int i = 0; i < 1000; i++) {
            if(i==200){
                try {
                    thread.join();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                }
            }
            System.out.println("main线程--"+i);
        }
    }
}

观测线程状态State

image

package com.mingmao.multithreading.commonmethod;

//观察测试线程的状态
//运行完之后的线程不能再次启动
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();
                } finally {
                }
                System.out.println("/////"+i);
            }
        });

        Thread.State state = thread.getState();
        System.out.println(state);//NEW

        thread.start();
        state = thread.getState();
        System.out.println(state);//RUNNABLE

        while (state!=Thread.State.TERMINATED){//如果线程没有终止,便持续输出线程状态
            Thread.sleep(100);
            state=thread.getState();
            System.out.println(state);//TIMED_WAITING
        }
    }
}

线程的优先级Priority

image

package com.mingmao.multithreading.commonmethod;

public class TestPriority {
    public static void main(String[] args) {
        System.out.println("主线程默认优先级为:"+Thread.currentThread().getName()+"--"+Thread.currentThread().getPriority());
        //主线程默认优先级为:main--5

        MyPriority myPriority=new MyPriority();
        Thread thread1=new Thread(myPriority,"线程1");
        Thread thread2=new Thread(myPriority,"线程2");
        Thread thread3=new Thread(myPriority,"线程3");
        Thread thread4=new Thread(myPriority,"线程4");
        Thread thread5=new Thread(myPriority,"线程5");
        Thread thread6=new Thread(myPriority,"线程6");

        //先设置优先级,再启动 1--慢,10-快
        thread1.start();
        thread2.setPriority(1);
        thread2.start();
        thread3.setPriority(4);
        thread3.start();
        thread4.setPriority(Thread.MAX_PRIORITY);
        thread4.start();
        thread5.setPriority(Thread.MIN_PRIORITY);
        thread5.start();
        thread6.setPriority(7);
        thread6.start();
    }
}

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

守护线程

image

package com.mingmao.multithreading.commonmethod;

//测试守护线程 上帝守护你
public class TestDaemonThread {
    public static void main(String[] args) {
        You you=new You();
        God god=new God();
        Thread thread=new Thread(god);
        Thread thread1=new Thread(you);

        thread.setDaemon(true);//默认是false,表示是用户线程
        thread.start();//上帝守护线程启动
        thread1.start();
    }
}

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

class God implements Runnable{
    @Override
    public void run() {
        while (true){
            System.out.println("上帝保佑着你");
        }
    }
}

线程同步

image
image
image
image

三大不安全案例

package com.mingmao.multithreading.synchronization;

//不安全的买票
//线程不安全,有负数
public class UnsafeTicketBuying implements Runnable {
    private int ticketNums=10;
    private boolean flag=true;

    @Override
    public void run() {
        while (flag){
            buy();
        }
    }

    public void buy(){
        if(ticketNums<=0){
            flag=false;
            return;
        }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        }
        System.out.println(Thread.currentThread().getName()+"买到了第"+ticketNums--+"张票");
    }

    public static void main(String[] args) {
        UnsafeTicketBuying unsafeTicketBuying=new UnsafeTicketBuying();
        new Thread(unsafeTicketBuying,"小明").start();
        new Thread(unsafeTicketBuying,"小红").start();
        new Thread(unsafeTicketBuying,"小丽").start();
    }
}
package com.mingmao.multithreading.synchronization;

//不安全的取钱
//存款出现负数
public class UnsafeBank {
    public static void main(String[] args) {
        Account account=new Account(500,"家庭存款");
        WithdrawMoney withdrawMoney=new WithdrawMoney(account,300,"小明");
        WithdrawMoney withdrawMoney1=new WithdrawMoney(account,500,"小明的老婆");
        withdrawMoney.start();
        withdrawMoney1.start();
    }
}
class Account{
    int money;//余额
    String name;//卡名

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

class WithdrawMoney extends Thread{
    Account account;
    int drawMoney;//取的钱数
    int nowMoney;//手中的钱

    public WithdrawMoney(Account account,int drawMoney,String name){
        super(name);
        this.account=account;
        this.drawMoney=drawMoney;
    }

    @Override
    public void run() {
        if((account.money-drawMoney)<0){
            System.out.println(Thread.currentThread().getName()+"你的卡中余额不足");
            return;
        }
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        }
        account.money-=drawMoney;
        nowMoney+=drawMoney;
        System.out.println(account.name+"余额为:"+account.money);
        System.out.println(this.getName()+"手里的钱为:"+nowMoney);
    }
}
package com.mingmao.multithreading.synchronization;

import java.util.ArrayList;
import java.util.List;

//不安全的线程
public class UnsafeList {
    public static void main(String[] args) {
        List<String> list=new ArrayList<>();
        for (int i = 0; i < 10000; i++) {
            new Thread(()->{
                list.add(Thread.currentThread().getName());
            }).start();
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        }
        System.out.println(list.size());//实际大小不是10000,线程不安全
    }
}

同步方法及同步块

image
image
image
锁住需要增删改的对象,注意锁的范围太大锁就会无效,比如100个人排队上厕所,把100个人全部锁在厕所里,锁就无效,只锁一个人锁才有效
同步方法:

package com.mingmao.multithreading.synchronizationmethod;

public class UnsafeTicketBuying implements Runnable {
    private int ticketNums=10;
    private boolean flag=true;

    @Override
    public void run() {
        while (flag){
            buy();
        }
    }

    public synchronized void buy(){
        if(ticketNums<=0){
            flag=false;
            return;
        }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        }
        System.out.println(Thread.currentThread().getName()+"买到了第"+ticketNums--+"张票");
    }

    public static void main(String[] args) {
        UnsafeTicketBuying unsafeTicketBuying=new UnsafeTicketBuying();
        new Thread(unsafeTicketBuying,"小明").start();
        new Thread(unsafeTicketBuying,"小红").start();
        new Thread(unsafeTicketBuying,"小丽").start();
    }
}

同步块:

package com.mingmao.multithreading.synchronizationmethod;

public class UnsafeBank {
    public static void main(String[] args) {
        Account account=new Account(500,"家庭存款");
        WithdrawMoney withdrawMoney=new WithdrawMoney(account,300,"小明");
        WithdrawMoney withdrawMoney1=new WithdrawMoney(account,500,"小明的老婆");
        withdrawMoney.start();
        withdrawMoney1.start();
    }
}

class Account{
    int money;//余额
    String name;//卡名

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

class WithdrawMoney extends Thread{
    Account account;
    int drawMoney;//取的钱数
    int nowMoney;//手中的钱

    public WithdrawMoney(Account account, int drawMoney, String name){
        super(name);
        this.account=account;
        this.drawMoney=drawMoney;
    }

    @Override
    public void run() {
        synchronized (account){
            if((account.money-drawMoney)<0){
                System.out.println(Thread.currentThread().getName()+"你的卡中余额不足");
                return;
            }
            try {
                Thread.sleep(1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
            }
            account.money-=drawMoney;
            nowMoney+=drawMoney;
            System.out.println(account.name+"余额为:"+account.money);
            System.out.println(this.getName()+"手里的钱为:"+nowMoney);
        }
    }
}
package com.mingmao.multithreading.synchronizationmethod;

import java.util.ArrayList;
import java.util.List;

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

CopyOnWriteArrayList

package com.mingmao.multithreading.synchronizationmethod;

import java.util.concurrent.CopyOnWriteArrayList;

//CopyOnWriteArrayList默认是线程安全的
public class TestJUC {
    public static void main(String[] args) {
        CopyOnWriteArrayList<String> copyOnWriteArrayList=new CopyOnWriteArrayList<>();
        for (int i = 0; i < 10000; i++) {
            new Thread(()->{
                copyOnWriteArrayList.add(Thread.currentThread().getName());
            }).start();
        }
        try {
            Thread.sleep(3000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        }
        System.out.println(copyOnWriteArrayList.size());
    }
}

死锁

image
死锁的情况:

package com.mingmao.multithreading.synchronizationmethod;

//死锁:多个线程互相抱着对方需要的资源,相互僵持
public class TestDeadLock {
    public static void main(String[] args) {
        MakeUp makeUp=new MakeUp(0,"小红");
        MakeUp makeUp1=new MakeUp(1,"小丽");
        makeUp.start();
        makeUp1.start();
    }
}

//口红
class Lipstick{

}

//镜子
class Mirror{

}

//化妆
class MakeUp extends Thread {
    //需要的资源只有一份,用static
    static Lipstick lipstick = new Lipstick();
    static Mirror mirror = new Mirror();

    private int choice;
    private String name;

    public MakeUp(int choice, String name) {
        this.choice = choice;
        this.name = name;
    }

    @Override
    public void run() {
        try {
            makeUp();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        }
    }

    //互相持有对方的锁,就是持有对方的资源
    private void makeUp() throws InterruptedException {
        if (choice == 0) {
            synchronized (lipstick) {
                System.out.println(this.name + "获得口红");
                Thread.sleep(1000);
                synchronized (mirror) {
                    System.out.println(this.name + "获得镜子");
                }
            }
        } else {
            synchronized (mirror) {
                System.out.println(this.name + "获得镜子");
                Thread.sleep(2000);
                synchronized (lipstick) {
                    System.out.println(this.name + "获得口红");
                }
            }
        }
    }
}

修改后:

package com.mingmao.multithreading.synchronizationmethod;

//死锁:多个线程互相抱着对方需要的资源,相互僵持
public class TestDeadLock {
    public static void main(String[] args) {
        MakeUp makeUp=new MakeUp(0,"小红");
        MakeUp makeUp1=new MakeUp(1,"小丽");
        makeUp.start();
        makeUp1.start();
    }
}

//口红
class Lipstick{

}

//镜子
class Mirror{

}

//化妆
class MakeUp extends Thread {
    //需要的资源只有一份,用static
    static Lipstick lipstick = new Lipstick();
    static Mirror mirror = new Mirror();

    private int choice;
    private String name;

    public MakeUp(int choice, String name) {
        this.choice = choice;
        this.name = name;
    }

    @Override
    public void run() {
        try {
            makeUp();
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
        }
    }

    //互相持有对方的锁,就是持有对方的资源
    private void makeUp() throws InterruptedException {
        if (choice == 0) {
            synchronized (lipstick) {
                System.out.println(this.name + "获得口红");
                Thread.sleep(1000);
            }
            synchronized (mirror) {
                System.out.println(this.name + "获得镜子");
            }
        } else {
            synchronized (mirror) {
                System.out.println(this.name + "获得镜子");
                Thread.sleep(2000);
            }
            synchronized (lipstick) {
                System.out.println(this.name + "获得口红");
            }
        }
    }
}

image

Lock锁

image
image

package com.mingmao.multithreading.lock;

import java.util.concurrent.locks.ReentrantLock;

//测试Lock锁
public class TestLock {
    public static void main(String[] args) {
        BuyTicket buyTicket=new BuyTicket();
        new Thread(buyTicket,"小明").start();
        new Thread(buyTicket,"小红").start();
        new Thread(buyTicket,"小丽").start();
    }
}

class BuyTicket implements Runnable{
    int ticketNums=10;
    //定义Lock锁
    private final ReentrantLock reentrantLock=new ReentrantLock();

    @Override
    public void run() {
        buyTicket();
    }

    public void buyTicket(){
        while (true){
            //加锁
            try {
                reentrantLock.lock();
                if(ticketNums<=0){
                    break;
                }
                try {
                    Thread.sleep(200);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                }
                System.out.println(Thread.currentThread().getName()+"买到了第"+ticketNums--+"张票");
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                reentrantLock.unlock();
            }
        }
    }
}

线程通信

image
image
image
image
image

管程法

package com.mingmao.multithreading.threadcommunication;

//测试生产者消费者模型--利用缓冲区解决:管程法
public class PipeProgramMethod {
    public static void main(String[] args) {
        Syncontainer syncontainer=new Syncontainer();

        new Producer(syncontainer).start();
        new Consumer(syncontainer).start();
    }
}

//生产者
class Producer extends Thread{
   Syncontainer syncontainer;

   public Producer(Syncontainer syncontainer){
       this.syncontainer=syncontainer;
   }

   //生产
    @Override
    public void run() {
        for (int i = 0; i <100; i++) {
            syncontainer.push(new Product(i));
            System.out.println("生产出了第"+(i+1)+"个产品");
        }
    }
}

//消费者
class Consumer extends Thread{
    Syncontainer syncontainer;

    public Consumer(Syncontainer syncontainer){
        this.syncontainer=syncontainer;
    }

    //消费
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("消费了第"+(syncontainer.pop().id+1)+"个产品");
        }
    }
}

//产品
class Product{
    int id;//产品编号

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

//缓冲区
class Syncontainer {
    private Product[] products = new Product[10];//容器大小
    private int num = 0;//产品数量

    //生产者放入产品
    public synchronized void push(Product product) {
        //容器满了,等待消费者消费
        if (num == products.length) {
            //通知消费者消费,生产者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
            }
        }

        //否则放入产品
        products[num] = product;
        num++;
        //通知消费者消费
        this.notifyAll();
    }

    //消费者消费产品
    public synchronized Product pop() {
        //判断是否有产品,没有就等待
        if (num == 0) {
            //等待生产者生产,消费者等待
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            } finally {
            }
        }

        //否则,取走产品
        num--;
        Product product = products[num];
        //吃完了,通知生产者生产
        this.notifyAll();
        return product;
    }
}

信号灯法

package com.mingmao.multithreading.threadcommunication;

//测试生产者消费者问题:信号灯法,标志位解决
public class SignalLampMethod {
    public static void main(String[] args) {
        TV tv=new TV();
        new Performer(tv).start();
        new Audience(tv).start();
    }
}

//生产者--演员
class Performer extends Thread{
    TV tv=new TV();

    public Performer(TV tv){
        this.tv=tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            tv.play("第"+(i+1)+"个节目");
        }
    }
}

//消费者--观众
class Audience extends Thread{
    TV tv=new TV();

    public Audience(TV tv){
        this.tv=tv;
    }

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            tv.watch("第"+(i+1)+"个节目");
        }
    }
}

//产品--节目
class TV{
    //演员表演,观众等待 true
    //观众观看,演员等待false
    String program;//节目
    private boolean flag=true;//标志

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

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

线程池

image

package com.mingmao.multithreading.pool;

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

public class TestPool {
    public static void main(String[] args) {
       /* 常规方法
       MyThread myThread=new MyThread();
        new Thread(myThread).start();
        */

       //创建服务,线程池
        ExecutorService executorService= Executors.newFixedThreadPool(10);//参数为线程池大小

        //执行
        executorService.execute(new MyThread());
        executorService.execute(new MyThread());
        executorService.execute(new MyThread());
        executorService.execute(new MyThread());

        //关闭连接
        executorService.shutdown();
    }
}

class MyThread implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println(Thread.currentThread().getName()+i);
        }
    }
}

学习视频

学习视频

posted @ 2021-09-15 11:32  明懋  阅读(44)  评论(0)    收藏  举报