多线程1.线程简介

文章插图

文章插图

文章插图
2.线程创建(重点)1.集成Thread类(重点)

文章插图
package com.jihu.Thread01;//创建多线程方式一: 继承Thread类,重写run()方法,调用start开启线程//总结: 注意,线程开启不一定立即执行,由CPU调度执行public class Demo01 extends Thread {@Overridepublic void run() {//run方法线程体for (int i = 0; i < 200; i++) {System.out.println("我是run方法");}}public static void main(String[] args) {//main线程,主线程//创建一个线程对象Demo01 demo01 = new Demo01();//调用start()方法开启线程demo01.start();for (int i = 0; i < 1000; i++) {System.out.println("我在学习多线程");}}}输出结果: (部分代码)我在学习多线程我在学习多线程我是run方法我是run方法我是run方法我是run方法我在学习多线程我在学习多线程我在学习多线程我在学习多线程网络图片下载 案例?需要导入 commons-io-2.6.jar这个包package com.jihu.Thread01;import org.apache.commons.io.FileUtils;import java.io.File;import java.io.IOException;import java.net.URL;//练习Thread,实现多线程同步下载图片public class TestThread02 extends Thread {private String url;//网络图片地址private String name;//保存的文件名public TestThread02(String url,String name){this.url = url;this.name= name;}//下载图片线程的执行体@Overridepublic void run() {WebDownLoader webDownLoader = new WebDownLoader();webDownLoader.downloader(url,name);System.out.println("下载了文件名为:"+name);}public static void main(String[] args) {TestThread02 t1 = new TestThread02("https://gitee.com/yin-jihu/images/raw/master/blog/20220306175925.png","1.png");TestThread02 t2 = new TestThread02("https://gitee.com/yin-jihu/images/raw/master/blog/20220306175654.png","2.png");TestThread02 t3 = new TestThread02("https://gitee.com/yin-jihu/images/raw/master/blog/20220305194641.jpg","3.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异常,Downloader方法出现问题");}}}输出结果:下载了文件名为:1.png下载了文件名为:3.jpg下载了文件名为:2.png2.实现Runnable(重点)package com.jihu.Thread01;//创建线程方式2:实现Runnable接口,重写run方法,执行线程需要丢入runnable接口实现类,调用start方法public class TestThread03 implements Runnable {@Overridepublic void run() {for (int i = 0; i < 20; i++) {//run方法线程体System.out.println("我是run()方法");}}public static void main(String[] args) {//创建runnable接口的实现类对象TestThread03 testThread03 = new TestThread03();//创建线程对象,通过线程对象来开启我们的线程,代理//Thread thread = new Thread();//thread.start();new Thread(testThread03).start();for (int i = 0; i < 100; i++) {System.out.println("我在学习多线程");}}}输出结果我在学习多线程我在学习多线程我是run()方法我是run()方法我是run()方法在学习多线程在学习多线程小结
文章插图
3.初识并发问题并发案例
package com.jihu.Thread01;//多个线程同时操作同一个对象//买火车票的例子//发现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱public class TestThread04 implements Runnable {//票数private int ticketNums = 10;@Overridepublic 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) {TestThread04 testThread04 = new TestThread04();new Thread(testThread04,"小明").start();new Thread(testThread04,"老师").start();new Thread(testThread04,"张三").start();}}输出结果张三-->拿到了第8票老师-->拿到了第9票老师-->拿到了第6票老师-->拿到了第5票老师-->拿到了第4票老师-->拿到了第3票老师-->拿到了第2票老师-->拿到了第1票张三-->拿到了第3票小明-->拿到了第10票张三-->拿到了第7票龟兔赛跑案例package com.jihu.Thread01;//模拟龟兔赛跑public class Race implements Runnable {//胜利者private static String winner;@Overridepublic void run() {for (int i = 0; i <= 100; i++) {//模拟兔子休息if (Thread.currentThread().getName().equals("兔子") && i%10==0){try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}//判断比赛是否结束Boolean flag = gameover(i);//如果比较结束了,就停止程序if (flag){break;}System.out.println(Thread.currentThread().getName()+"-->跑了"+i+"步");}}//判断是否完成比赛public Booleangameover(int steps){//判断是否有胜利者if (winner != null){//已经存在胜利者了return true;}if (steps >=100){winner = Thread.currentThread().getName();System.out.println("winner is :"+winner);returntrue;}return false;}public static void main(String[] args) {Race race = new Race();new Thread(race,"乌龟").start();new Thread(race,"兔子").start();}}输出结果乌龟-->跑了97步乌龟-->跑了98步乌龟-->跑了99步winner is :乌龟4.实现Callable接口(了解)
文章插图
案例
package com.jihu.Demo02;import org.apache.commons.io.FileUtils;import java.io.File;import java.io.IOException;import java.net.URL;import java.util.concurrent.*;//线程创建方式三: 实现callable接口/*callable的好处1.可以定义返回值2.可以抛出异常 */public class TestCallable implements Callable<Boolean> {private String url;//网络图片地址private String name;//保存的文件名public TestCallable(String url,String name){this.url = url;this.name= name;}//下载图片线程的执行体@Overridepublic Boolean call() {WebDownLoader webDownLoader = new WebDownLoader();webDownLoader.downloader(url,name);System.out.println("下载了文件名为:"+name);return true;}public static void main(String[] args) throws ExecutionException, InterruptedException {TestCallable t1 = new TestCallable("https://gitee.com/yin-jihu/images/raw/master/blog/20220306175925.png","1.png");TestCallable t2 = new TestCallable("https://gitee.com/yin-jihu/images/raw/master/blog/20220306175654.png","2.png");TestCallable t3 = new TestCallable("https://gitee.com/yin-jihu/images/raw/master/blog/20220305194641.jpg","3.jpg");//创建执行服务ExecutorService ser = Executors.newFixedThreadPool(3);//提交执行Future<Boolean> r1 = (Future<Boolean>) ser.submit(t1);Future<Boolean> r2= (Future<Boolean>) ser.submit(t2);Future<Boolean> r3 = (Future<Boolean>) ser.submit(t3);//获取结果Boolean rs1 = r1.get();Boolean rs2 = r2.get();Boolean rs3 = r3.get();System.out.println(rs1);//trueSystem.out.println(rs2);//trueSystem.out.println(rs3);//true//关闭服务ser.shutdownNow();}}//下载器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异常,Downloader方法出现问题");}}}输出结果:下载了文件名为:1.png下载了文件名为:3.jpg下载了文件名为:2.pngtruetruetrue3.静态代理模式婚庆公司的案例package com.jihu.Demo02;/*静态代理模式总结:真实对象和dialing对象都要实现同一个接口代理对象要代理真实角色 *//* 好处:代理对象可以做很多真实对象做不了的事情真实对象专注做自己的事情 */public class StacticProxy {public static void main(String[] args) {//You you = new You();//WeddingCompany weddingCompany = new WeddingCompany(you);new Thread( ()-> System.out.println("我爱你")).start();WeddingCompany weddingCompany = new WeddingCompany(new You());weddingCompany.HappyMarry();}}interface Marry{void HappyMarry();}//真实角色,你去结婚class You implements Marry{@Overridepublic void HappyMarry() {System.out.println("老师我要结婚了,超开森");}}//代理角色,帮助你结婚class WeddingCompany implements Marry{//代理谁 --> 真实目标角色private Marry target;public WeddingCompany(Marry target) {this.target = target;}@Overridepublic void HappyMarry() {before();this.target.HappyMarry();//这就是真实对象 。after();}private void after() {System.out.println("结婚之后,收尾款");}private void before() {System.out.println("结婚之前,布置现场");}}输出结果:我爱你结婚之前,布置现场老师我要结婚了,超开森结婚之后,收尾款4.Lamda表达式
文章插图

文章插图
案例1:
package com.jihu.lamda;//推到lamda表达式public class TestLamda {//3.静态内部类staticclass Like2 implementsILike{@Overridepublic void lamda() {System.out.println(" i like lamda2");}}public static void main(String[] args) {ILike like = new Like();like.lamda();Like2 like2 = new Like2();like2.lamda();//4.局部内部类class Like3 implementsILike{@Overridepublic void lamda() {System.out.println(" i like lamda3");}}Like3 like3 = new Like3();like3.lamda();//5.匿名内部类,没有类的名称,必须借助接口或者父类like = new ILike() {@Overridepublic void lamda() {System.out.println(" i like lamda4");}};like.lamda();//6.用lamda简化like =() ->{System.out.println(" i like lamda5");};like.lamda();}}//1.定义一个函数式接口interfaceILike{void lamda();}//2.实现类class Like implementsILike{@Overridepublic void lamda() {System.out.println(" i like lamda");}}输出结果 i like lamda i like lamda2 i like lamda3 i like lamda4 i like lamda5案例2package com.jihu.lamda;/*总结lamda表达式只能有一行代码的情况下才能简化成为一行,如果有多行,那么就用代码块包裹 。前提是接口为函数式接口多个参数也可以去掉参数类型,要去掉就都去掉,必须加上括号 */public class TestLamda2 {public static void main(String[] args) {Ilove love = null;/*class Love implements Ilove{@Overridepublic void love(int a) {System.out.println(" i love you "+a);}}*///1.lamda表示简化/* love = (int a)-> {System.out.println(" i love you "+a);};*///.简化1.参数类型love = (a)->{System.out.println(" i love you "+a);};//简化2.简化括号/* love = a->{System.out.println(" i love you "+a);System.out.println(" i love you -->too ");};*///简化3. 去掉花括号love = a -> System.out.println(" i love you "+a);love.love(520);/*总结lamda表达式只能有一行代码的情况下才能简化成为一行,如果有多行,那么就用代码块包裹 。前提是接口为函数式接口多个参数也可以去掉参数类型,要去掉就都去掉,必须加上括号*/}}interface Ilove{voidlove(int a);}输出结果i love you 520案例3package com.jihu.lamda;public class TestLamda3 {public static void main(String[] args) {car car=(a,b,c)->System.out.println("购买的汽车"+a+b+c);car.buychar(10,54,78);}}interface car{void buychar(int a,int b,int c);}输出结果:购买的汽车1054783.线程状态线程状态概况:
文章插图

文章插图

文章插图
1.线程停止

文章插图
package com.jihu.state;/* 测试 stop1.建议线程正常停止 --> 利用次数,不建议死循环2.建议使用标志位 -->设置一个标志位3.不要使用stop或者destroy 等过时或者JDK不建议使用的方法 */public class TestStop implements Runnable {//1.设置一个标识位privateboolean flag = true;@Overridepublic void run() {int i =0;while (flag){System.out.println("run ... Thread"+ i++);}}//2.设置一个公开的方法停止线程,转换标志位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);//调用stop方法切换标志位,让线程停止if (i==900){testStop.stop();System.out.println("线程该停止了");}}}}输出结果:main898run ... Thread2338main899run ... Thread2339main900run ... Thread2340run ... Thread2341线程该停止了main901main902main997main998main9992.线程休眠_sleep
文章插图
package com.jihu.state;import com.jihu.Thread01.TestThread04;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 (Exception exception) {exception.printStackTrace();}}}//模拟倒计时public static void tenDown() throws InterruptedException {int num = 10;while (true){Thread.sleep(1000);//1000等于1毫秒System.out.println(num--);if (num<=0){break;}}}}输出结果:23:27:4123:27:4223:27:4323:27:4423:27:4523:27:4623:27:473.线程礼让_yield
文章插图
package com.jihu.state;//测试礼让线程//礼让不一定成功,看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{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+":start");Thread.yield(); //礼让System.out.println(Thread.currentThread().getName()+":end");}}输出结果:B:startA:startB:endA:end4.线程强制执行_joinjoin合并线程,待此线程执行完成后,再执行其他线程,其他线程阻塞可以想象为插队
package com.jihu.state;//测试join方法想象为插队public class TestJoin implements Runnable{@Overridepublic void run() {for (int i = 0; i < 1000; 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 < 300; i++) {if (i==200){thread.join(); //插队}System.out.println("main:"+i);}}}输出结果线程vip来了996线程vip来了997线程vip来了998线程vip来了999main:200main:201main:202main:203main:204main:2055.观测线程状态
文章插图
package com.jihu.state;//观察测试线程的状态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);//New//观察启动后thread.start();//启动线程state = thread.getState();System.out.println(state);//Runwhile (Thread.State.TERMINATED != state){Thread.sleep(100);state= thread.getState(); //更新线程状态System.out.println(state);//输出状态}}}输出结果:NEWRUNNABLETIMED_WAITINGTIMED_WAITINGTIMED_WAITINGTIMED_WAITING///////TERMINATED6.线程的优先级
文章插图
package com.jihu.state;//测试线程的优先级public class TestPriority{public static void main(String[] args) {//主线程默认优先级System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority());MyPriority myPriority = new MyPriority();Thread t1 = new Thread(myPriority);Thread t2 = new Thread(myPriority);Thread t3 = new Thread(myPriority);Thread t4 = new Thread(myPriority);Thread t5 = new Thread(myPriority);Thread t6 = new Thread(myPriority);//先设置优先级,在启动t1.start();t2.setPriority(1);t2.start();t3.setPriority(4);t3.start();t4.setPriority(Thread.MAX_PRIORITY);//MAX_PRIORITY=10t4.start();t5.setPriority(8);t5.start();t6.setPriority(7);t6.start();}}class MyPriority implements Runnable{@Overridepublic void run() {System.out.println(Thread.currentThread().getName()+"--->"+Thread.currentThread().getPriority());}}输出结果:main--->5Thread-3--->10Thread-4--->8Thread-5--->7Thread-2--->4Thread-0--->5Thread-1--->17.守护线程(daemon)
文章插图
package com.jihu.state;//测试守护线程//上帝守护你public class TestDaemon {public static void main(String[] args) {God god = new God();You you = new You();Thread thread = new Thread(god);thread.setDaemon(true); //默认是false表示是用户线程,正常的线程都是用户线程..thread.start();//开启上帝线程启动new Thread(you).start(); //你用户线程启动}}//上帝class God implements Runnable{@Overridepublic void run() {System.out.println("上帝一直保佑着你!");}}//你class You implements Runnable{@Overridepublic void run() {for (int i = 0; i < 365; i++) {System.out.println("你一生都开心的活着!");}System.out.println("============goodbyeworld!===============");}}输出结果:你一生都开心的活着!你一生都开心的活着!你一生都开心的活着!你一生都开心的活着!你一生都开心的活着!你一生都开心的活着!你一生都开心的活着!你一生都开心的活着!============goodbyeworld!===============上帝一直保佑着你!4.线程同步(重点)
文章插图
1.三大不安全案例案例1
package com.jihu.syn;//不安全的买票//线程不安全有负数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{//票privateint ticketNums = 10;Boolean flag = true;//外部停止方式@Overridepublic void run() {//买票while (flag){try {buy();} catch (InterruptedException e) {e.printStackTrace();}}}private void buy() throws InterruptedException {//判断是否有票if (ticketNums <= 0){flag = false;return;}//模拟延迟Thread.sleep(1000);//买票System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);}}输出结果牛逼的你们拿到9可恶的黄牛党拿到10苦逼的我拿到8苦逼的我拿到7可恶的黄牛党拿到6牛逼的你们拿到5可恶的黄牛党拿到3苦逼的我拿到2牛逼的你们拿到4牛逼的你们拿到0可恶的黄牛党拿到1苦逼的我拿到-1案例2package com.jihu.syn;//不安全的取钱//两个人去银行取钱, 账户public class UnSafeBank {public static void main(String[] args) {//账户Acount acount = new Acount(100,"结婚基金");Bank you = new Bank(acount,50,"你");Bank youwife = new Bank(acount,100,"你妻子");you.start();youwife.start();}}//账户class Acount{int money; //余额String name; //卡名public Acount(int money, String name) {this.money = money;this.name = name;}}//银行:模拟取款classBank extendsThread{Acount acount;//账户//取了多少钱int drawingMoney;//现在手里有多少钱int nowMoney;public Bank(Acount acount,int drawingMoney,String name){super(name);this.acount = acount;this.drawingMoney = drawingMoney;}//取钱@Overridepublic void run() {//判断有没有钱if (acount.money - drawingMoney <0){System.out.println(Thread.currentThread().getName()+"钱不够,取不了");}//sleep可以放大问题的发生性try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//卡内余额 = 余额-你取的钱acount.money = acount.money - drawingMoney;//你手里的钱nowMoney = nowMoney + drawingMoney;System.out.println(acount.name + "余额为:"+acount.money);//Thread.currentThread().getName()== this.getName()System.out.println(this.getName() + "手里的钱:"+nowMoney);}}输出结果:结婚基金余额为:50你手里的钱:50你妻子钱不够,取不了案例3package com.jihu.syn;import java.util.ArrayList;import java.util.List;//线程不安全的集合public class UnSafeList {public static void main(String[] args) {List<String> list = new ArrayList<>();try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}for (int i = 0; i < 1000; i++) {new Thread(()->{list.add(Thread.currentThread().getName());}).start();}System.out.println(list.size());}}输出结果:9962.同步方法及同步块
文章插图

文章插图
把前面三个案例改为同步
案例一
//synchronized同步方法,锁的是thisprivate synchronized void buy() throws InterruptedException {//判断是否有票if (ticketNums <= 0){flag = false;return;}//模拟延迟Thread.sleep(1000);//买票System.out.println(Thread.currentThread().getName()+"拿到"+ticketNums--);}案例二//取钱//synchronized默认锁的是this@Overridepublic void run() {//同步块//锁的对象就是变化的量, 需要增删改的对象synchronized (acount){//判断有没有钱if (acount.money - drawingMoney <0){System.out.println(Thread.currentThread().getName()+"钱不够,取不了");return;}//sleep可以放大问题的发生性try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//卡内余额 = 余额-你取的钱acount.money = acount.money - drawingMoney;//你手里的钱nowMoney = nowMoney + drawingMoney;System.out.println(acount.name + "余额为:"+acount.money);//Thread.currentThread().getName()== this.getName()System.out.println(this.getName() + "手里的钱:"+nowMoney);}}案例三//线程不安全的集合public class UnSafeList {public static void main(String[] args) {List<String> list = new ArrayList<>();try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}for (int i = 0; i < 1000; i++) {new Thread(()->{//synchronized 锁住listsynchronized (list){list.add(Thread.currentThread().getName());}}).start();}System.out.println(list.size());}}3.JUC安全类型的集合(CopyOnWriteArrayList)package com.jihu.syn;import java.util.concurrent.CopyOnWriteArrayList;//测试JUC安全类型的集合public class TestJUC {public static void main(String[] args) {CopyOnWriteArrayList<String> list = new CopyOnWriteArrayList<>();for (int i = 0; i < 1000; i++) {new Thread(()->{list.add(Thread.currentThread().getName());}).start();}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(list.size());}}输出结果:10004.死锁
文章插图
package com.jihu.Thread05;//死锁: 多个线程互相抱着对方需要的资源,然后形成僵持public class DeadLock {public static void main(String[] args) {Makeup makeup = new Makeup(0,"灰姑娘");Makeup makeup2 = new Makeup(1,"白雪公主");makeup.start();makeup2.start();}}//口红class Lipstick{}//镜子classMirror{}class Makeup extendsThread{//需要的资源只有一份,用static来保证只有一份static Lipstick lipstick = new Lipstick();static Mirror mirror = new Mirror();int choice;//选择String girlName;//使用化妆品的人public Makeup(int choice,String girlName){this.choice = choice;this.girlName = girlName;}@Overridepublic void 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) { //1秒中后获得镜子的锁System.out.println(this.girlName + "获得镜子的锁");}}}else {synchronized (mirror) { //获得镜子的锁System.out.println(this.girlName + "获得镜子的锁");Thread.sleep(2000);synchronized (lipstick) { //2秒中后获得口红的锁System.out.println(this.girlName + "获得口红的锁");}}}}}输出结果://会发生死锁灰姑娘获得口红的锁白雪公主获得镜子的锁//这样会解除死锁//化妆,互相持有对方的锁,就是需要拿到对方的资源private void makeup() throws InterruptedException {if (choice == 0) {synchronized (lipstick) { //获得口红的锁System.out.println(this.girlName + "获得口红的锁");Thread.sleep(1000);}synchronized (mirror) { //1秒中后获得镜子的锁////这样会解除死锁System.out.println(this.girlName + "获得镜子的锁");}}else {synchronized (mirror) { //获得镜子的锁System.out.println(this.girlName + "获得镜子的锁");Thread.sleep(2000);}synchronized (lipstick) { //2秒中后获得口红的锁System.out.println(this.girlName + "获得口红的锁");}}}输出结果:////这样会解除死锁灰姑娘获得口红的锁白雪公主获得镜子的锁白雪公主获得口红的锁灰姑娘获得镜子的锁
文章插图
5.Lock锁

文章插图

文章插图
package com.jihu.Thread05;import java.util.concurrent.locks.ReentrantLock;public class TestLock {public static void main(String[] args) {BuyTicket buyTicket = new BuyTicket();new Thread(buyTicket,"a").start();new Thread(buyTicket,"c").start();new Thread(buyTicket,"b").start();}}class BuyTicket implements Runnable{int TicketNums = 10;//定义lock锁private ReentrantLock lock =new ReentrantLock();@Overridepublic void run() {while (true){try {lock.lock(); //加锁if (TicketNums >0){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"获得了"+ TicketNums--+"票");}else{break;}} finally {lock.unlock();//解锁}}}}输出结果a获得了10票a获得了9票c获得了8票b获得了7票a获得了6票a获得了5票c获得了4票b获得了3票a获得了2票a获得了1票6.synchronized与lock的对比
文章插图
5.线程协作1.生产者消费者问题【对多线程的通俗理解 多线程详解】

文章插图

文章插图
2.解决方式1 -->管程法

文章插图
package com.jihu.gaoji;//测试: 生产者消费者模型 -> 利用缓冲区解决:管程法//生产者 , 消费者 ,产品,缓冲区public class TestPC {public static void main(String[] args) {SynContainer container = new SynContainer();new Productor(container).start();new Customer(container).start();}}//生产者class Productor extends Thread{SynContainer container;publicProductor(SynContainer container){this.container = container;}//生产@Overridepublic void run() {for (int i = 0; i < 100; i++) {container.push(new Chicken(i));System.out.println("生产了"+i+"只鸡");}}}//消费者classCustomer extendsThread{SynContainer container;publicCustomer(SynContainer container){this.container = container;}//消费@Overridepublic 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 voidpush(Chicken chicken){//如果容器满了,就需要等待消费者消费if (count ==chickens.length){//通知消费者消费,生产者等待try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}//如果没有满,我们就需要丢入产品chickens[count++] = chicken;//可以通知消费者消费了this.notifyAll();}//消费者消费产品publicsynchronized Chickenpop(){//判断是否能消费if (count == 0 ){//等待生产者生产,消费者等待try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}//如果可以消费count--;Chicken chicken = chickens[count];//吃完了,通知生产者生产this.notifyAll();return chicken;}}输出结果消费了-->75只鸡生产了76只鸡消费了-->76只鸡生产了77只鸡消费了-->77只鸡生产了78只鸡消费了-->78只鸡生产了79只鸡消费了-->79只鸡生产了80只鸡消费了-->80只鸡3.解决方式2 -->信号灯法
文章插图
package com.jihu.gaoji;//测试生产者消费者问题2: 信号灯法,标志位解决public class TestPC2 {public static void main(String[] args) {TV tv = new TV();newPlayer(tv).start();new Watcher(tv).start();}}//生产者-->演员class Player extends Thread{TV tv;public Player(TV tv) {this.tv = tv;}@Overridepublic 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;}@Overridepublic void run() {for (int i = 0; i < 20; i++) {tv.watch();}}}//产品-->节目class TV{//演员表演,观众等待 T//观众观看,演员等待 FString 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 voidwatch(){if (flag){try {this.wait();} catch (InterruptedException e) {e.printStackTrace();}}System.out.println("观看了:"+voice);//通知演员表演this.notifyAll();this.flag = !this.flag;}}输出结果:演员表演了:快乐大本营播放中观看了:快乐大本营播放中演员表演了:抖音:记录美好生活观看了:抖音:记录美好生活演员表演了:快乐大本营播放中观看了:快乐大本营播放中演员表演了:抖音:记录美好生活观看了:抖音:记录美好生活演员表演了:快乐大本营播放中观看了:快乐大本营播放中4.线程池
文章插图

文章插图
package com.jihu.gaoji;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;//测试线程池public class TestPool {public static void main(String[] args) {//1.创建服务,创建线程池//newFixedThreadPool参数为:线程池大小ExecutorService service = Executors.newFixedThreadPool(10);//执行service.execute(new MyThread());service.execute(new MyThread());service.execute(new MyThread());service.execute(new MyThread());//2.关闭连接service.shutdownNow();}}class MyThread implements Runnable{@Overridepublic void run() {/* for (int i = 0; i < 2; i++) {System.out.println(Thread.currentThread().getName()+i);}*/System.out.println(Thread.currentThread().getName());}}输出结果:pool-1-thread-1pool-1-thread-4pool-1-thread-2pool-1-thread-35.总结package com.jihu.gaoji;import java.util.concurrent.Callable;import java.util.concurrent.ExecutionException;import java.util.concurrent.FutureTask;public class Demo03 {public static void main(String[] args) {/*MyThread1 myThread = new MyThread1();myThread.start();*/new MyThread1().start();new Thread(new MyThread2()).start();FutureTask<Integer> futureTask = new FutureTask<Integer>(new MyThread3());new Thread(futureTask).start();try {Integer integer = futureTask.get();System.out.println(integer);} catch (InterruptedException e) {e.printStackTrace();} catch (ExecutionException e) {e.printStackTrace();}}}//1.继承Thread类class MyThread1 extends Thread{@Overridepublic void run() {System.out.println("MyThread1");}}//2.实现Runnable接口class MyThread2 implements Runnable{@Overridepublic void run() {System.out.println("MyThread2");}}//3.实现Runnable接口class MyThread3 implements Callable<Integer>{@Overridepublic Integer call() throws Exception {System.out.println("MyThread3");return 100;}}输出结果:MyThread1MyThread2MyThread3100收藏关注评论
- 春季老年人吃什么养肝?土豆、米饭换着吃
- 三八妇女节节日祝福分享 三八妇女节节日语录
- 老人谨慎!选好你的“第三只脚”
- 校方进行了深刻的反思 青岛一大学生坠亡校方整改校规
- 脸皮厚的人长寿!有这特征的老人最长寿
- 长寿秘诀:记住这10大妙招 100%增寿
- 春季老年人心血管病高发 3条保命要诀
- 眼睛花不花要看四十八 老年人怎样延缓老花眼
- 香槟然能防治老年痴呆症? 一天三杯它人到90不痴呆
- 老人手抖的原因 为什么老人手会抖
