多线程--技术总结
一、 线程核心概念
- 线程是独立的执行路径
- 在程序运行时,即使没有自己创建线程,后台也会有多个线程,比如:主线程、gc线程
- main()称之为主线程,为系统的入口,用于执行整个程序
- 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序是不能人为干预的。
- 对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制
- 线程会带来额外的开销,如:cpu调度时间、并发控制开销。
- 每个线程在自己的工作内存交互,内存控制不当就会造成数据不一致。
二、创建方式(三种)
-
继承Thread类(重点)
TestThread01
package com.kuang.demo01; /** * 创建线程方式一: * 继承Thread类 * 重写run()方法 * 调用start开启线程 */ public class TestThread01 extends Thread { @Override public void run() { //run方法线程体 for (int i = 0; i <200 ; i++) { System.out.println("我在看代码--"+i); } } //main线程,主线程 public static void main(String[] args) { //创建一个线程对象 TestThread01 testThread01 = new TestThread01(); //调用start()方法开启线程 //testThread01.start(); testThread01.run(); for (int i = 0; i <200 ; i++) { System.out.println("我在学习多线程"+i); } } }
TestThread02
测试之前先去下载
把包下的commons-io-2.9.0.jar复制到项目的lib目录下(手动添加一个lib包),之后选中lib,右键>Add as Library,就可以了
package com.kuang.demo01; 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; } //下载图片线程的执行提 @Override public 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://img2.baidu.com/it/u=887918930,2064725991&fm=26&fmt=auto&gp=0.jpg","张天爱1.jpg"); TestThread02 t2 = new TestThread02("https://img2.baidu.com/it/u=3810345217,1257588557&fm=26&fmt=auto&gp=0.jpg","张天爱2.jpg"); TestThread02 t3 = new TestThread02("https://img0.baidu.com/it/u=2867474920,409094384&fm=26&fmt=auto&gp=0.jpg","张天爱3.jpg"); //启动线程 t1.start(); t2.start(); t3.start(); } } //下载器 class WebDownLoader{ //下载方法 public void downLoader(String url,String name){ //引入FileUtils工具类 try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("IO异常,downLoader方法出现问题!"); } } }
-
实现Runnable接口(重点)
package com.kuang.demo01; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URL; /** * 联系Thread * 实现多线程同步下载图片 */ public class TestThread02 implements Runnable { private String url;//网络图片地址 private String name;//保存的文件名 public TestThread02(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) { TestThread02 t1 = new TestThread02("https://img2.baidu.com/it/u=887918930,2064725991&fm=26&fmt=auto&gp=0.jpg","张天爱1.jpg"); TestThread02 t2 = new TestThread02("https://img2.baidu.com/it/u=3810345217,1257588557&fm=26&fmt=auto&gp=0.jpg","张天爱2.jpg"); TestThread02 t3 = new TestThread02("https://img0.baidu.com/it/u=2867474920,409094384&fm=26&fmt=auto&gp=0.jpg","张天爱3.jpg"); //启动线程 new Thread(t1).start(); new Thread(t2).start(); new Thread(t3).start(); } } //下载器 class WebDownLoader{ //下载方法 public void downLoader(String url,String name){ //引入FileUtils工具类 try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("IO异常,downLoader方法出现问题!"); } } }
龟兔赛跑
package com.kuang.demo01; /** * 模拟龟兔赛跑 */ 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(100); } 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; } { if (steps>=100){ winner=Thread.currentThread().getName(); System.out.println("胜利者是"+winner); return true; } } return false; } public static void main(String[] args) { Race race = new Race(); new Thread(race,"兔子").start(); new Thread(race,"乌龟").start(); } }
-
实现Callable接口(了解)
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; } //下载图片线程的执行提 @Override public 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://img2.baidu.com/it/u=887918930,2064725991&fm=26&fmt=auto&gp=0.jpg","张天爱1.jpg"); TestCallable t2 = new TestCallable("https://img2.baidu.com/it/u=3810345217,1257588557&fm=26&fmt=auto&gp=0.jpg","张天爱2.jpg"); TestCallable t3 = new TestCallable("https://img0.baidu.com/it/u=2867474920,409094384&fm=26&fmt=auto&gp=0.jpg","张天爱3.jpg"); //创建执行服务 ExecutorService ser = Executors.newFixedThreadPool(3); //提交执行 Future<Boolean> r1 = ser.submit(t1); Future<Boolean> r2 = ser.submit(t2); Future<Boolean> r3 = ser.submit(t3); //获取结果 Boolean rs1 = r1.get(); Boolean rs2 = r2.get(); Boolean rs3 = r3.get(); System.out.println(rs1); System.out.println(rs2); System.out.println(rs3); //关闭服务 ser.shutdownNow(); } } //下载器 class WebDownLoader{ //下载方法 public void downLoader(String url,String name){ //引入FileUtils工具类 try { FileUtils.copyURLToFile(new URL(url),new File(name)); } catch (IOException e) { e.printStackTrace(); System.out.println("IO异常,downLoader方法出现问题!"); } } }
三、静态代理模式
-
举例
package com.kuang.staticProxy; /** * 静态代理模式总结: * 真实对象和代理对象都要实现同一个接口 * 代理对象要代理真实角色 * * 好处: * 代理对象可以做很多真实对象做不了的事情 * 真实对象专注做自己的事情 */ public class StaticProxy { public static void main(String[] args) { You you = new You();//你要结婚 new Thread(()-> System.out.println("我爱你")).start();//thread方法类似以下的代理模式 new WeddingCompany(new You()).HappyMarry();//自己写的代理模式 } } interface Marry{ /** * 人间四大喜事 * 1.金榜题名时 * 2.他乡遇故知 * 3.久旱逢甘霖 * 4.洞房花烛夜 */ 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("结婚之后,收款"); } }
四、Lambda表达式
-
Test1:
package com.kuang.lambda; /** * 推导lambda表达式 */ public class TestLambda01 { //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"); } }
-
Test2
package com.kuang.lambda; public class TestLambda02 { public static void main(String[] args) { Ilove love=null; //1.lambda表达式简化 /* love = (int a,int b)->{ System.out.println("我爱你-->"+a); };*/ //简化1:参数类型 /*love = (a,b)->{ System.out.println("我爱你-->"+a); };*/ //简化3:去掉花括号 /*love=a->System.out.println("我爱你-->"+a);*/ //简化2:简化括号 love = (a,b)->{ System.out.println("我爱你-->"+a); System.out.println("我爱你-->"+b); }; love.love(521,520); /** * 总结: * lambda表达式只能有一行代码的情况下才能简化成为一行,如果有多行,就用代码块包裹 * 前提是接口必须是函数式接口(只有一个方法的接口) * 多个参数也可以去掉参数类型,要去掉就都去掉,必须加上括号 */ } } interface Ilove{ void love(int a,int b); }
五、线程状态
new-->就绪-->运行-->阻塞-->dead
线程一旦进入死亡状态,就不能再次启动了
-
线程停止
package com.kuang.status; /** * 线程停止 * 1.建议线程正常停止--利用次数,不建议死循环 * 2.建议使用标志位--设置一个标志位 * 3.不要使用stop、destroy等过时或者JDK不建议使用的方法 */ public class TestStop implements Runnable { //1.设置一个标志位 private boolean flag=true; @Override public 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); if (i==900){ //调用自己写的stop方法,切换标志位,让线程停止 testStop.stop(); System.out.println("线程停止了"); } } } }
-
线程休眠
-
Test1--模拟网络延时
package com.kuang.status; /** * 模拟网络延时:放大问题的发生性 * 每一个对象都有一把锁,sleep不会释放锁 */ public class TestSleep implements Runnable { //票数 private int ticketNums=10; @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) { TestSleep ticket = new TestSleep(); new Thread(ticket,"貂蝉").start(); new Thread(ticket,"吕布").start(); new Thread(ticket,"小乔").start(); } }
-
Test2--模拟倒计时
package com.kuang.status; import java.text.SimpleDateFormat; import java.util.Date; /** * 模拟倒计时 */ public class TestSleep02 { public static void main(String[] args) { //打印当前系统时间 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=20; while (true){ Thread.sleep(1000); System.out.println(num--); if (num<=0){ break; } } } }
-
-
线程礼让
-
礼让不一定成功,看CPU心情
package com.kuang.status; /** * 线程礼让 * 礼让不一定成功,看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()+"线程停止执行"); } }
-
-
观察测试线程的状态
-
测试
package com.kuang.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);//Run while (state!=Thread.State.TERMINATED){//只要线程不终止,就一直输出状态 Thread.sleep(100); state=thread.getState();//更新线程状态 System.out.println(state); } } }
-
六、线程优先级
-
测试
-
测试代码
package com.kuang.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);//最大==10 t4.start(); t5.setPriority(8); t5.start(); t6.setPriority(7); t6.start(); } } class MyPriority implements Runnable{ @Override public void run() { System.out.println(Thread.currentThread().getName()+"-->"+Thread.currentThread().getPriority()); } }
-
七、守护线程
-
测试
-
测试代码
package com.kuang.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{ @Override public void run() { while (true){ System.out.println("上帝一直保佑着你,加油!"); } } } //你 class You implements Runnable{ @Override public void run() { for (int i = 0; i < 36500; i++) { System.out.println("你一生都开心的活着!"); } System.out.println("=========再见,这个世界======================!"); } }
-
八、线程同步(重点)
-
举例
-
买票
package com.kuang.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{ 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(1000); System.out.println(Thread.currentThread ().getName()+"拿到"+ticketNums--); } }
-
取钱
package com.kuang.syn; /** * 不安全的取钱 * 两个人去银行取钱 */ public class UnSafeBank { public static void main(String[] args) { //账户 Account account = new Account(1000,"买车资金"); //你 Drawing you = new Drawing(account,50,"你"); //girlFriend Drawing girlFriend = new Drawing(account,100,"girlFriend"); you.start(); girlFriend.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.kuang.syn; import java.util.ArrayList; import java.util.List; /** * 线程不安全的集合 */ public class UnSafeList { public static void main(String[] args) throws InterruptedException { List<String > list=new ArrayList<String>(); 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()); } }
-
测试JUC安全类型的集合
package com.kuang.syn; 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()); } }
-
-
死锁
-
产生死锁的四个必要条件
-
测试代码:
package com.kuang.syn; /** * 死锁:多个线程互相抱着对方需要的资源,然后形成僵持 * */ 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来保证只有一份 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() { //化妆 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+"获得镜子的锁"); } }else { synchronized (mirror){//获得镜子的锁 System.out.println(this.girlName+"获得镜子的锁"); Thread.sleep(2000); } synchronized (lipstick){//2秒后想获得口红 System.out.println(this.girlName+"获得口红的锁"); } } } }
-
-
Lock锁
-
测试代码
package com.kuang.gaoji; import java.util.concurrent.locks.ReentrantLock; /** * 测试lock锁 */ 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(); } } } }
-
-
并发协作模型“生产者/消费者模式”----管程法
-
举例:
package com.kuang.gaoji; /** * 测试:生产者消费者模型:-->利用缓冲区解决:管程法 * * 生产者、消费者、产品、缓冲区 */ public class TestPC { public static void main(String[] args) { SynContainer synContainer = new SynContainer(); new Productor(synContainer).start(); new Consumer(synContainer).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; } }
-
-
并发协作模型“生产者/消费者模式”----信号灯法
-
举例
package com.kuang.gaoji; /** * 测试:生产者消费者模型:-->利用缓冲区解决:信号灯法--标志位解决 */ 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++) { this.tv.watch(); } } } //产品--节目 class TV{ //演员表演,观众等待--true //观众观看,演员等待--false 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; } }
-
九、线程池
-
package com.kuang.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.shutdown(); } } class MyThread implements Runnable{ @Override public void run() { for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName()+i); } } }
十、总结
package com.kuang.gaoji;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
/**
* 线程的总结
*/
public class ThreadNew {
public static void main(String[] args) {
//启动线程1
new MyThread1().start();
//启动线程2
new Thread(new MyThread2()).start();
//启动线程3
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{
@Override
public void run() {
System.out.println("MyThread1");
}
}
//2.实现Runnable接口
class MyThread2 implements Runnable{
@Override
public void run() {
System.out.println("MyThread2");
}
}
//3.实现Callable接口
class MyThread3 implements Callable<Integer>{
@Override
public Integer call() throws Exception {
System.out.println("MyThread3");
return 100;
}
}
本文来自博客园,作者:青喺半掩眉砂,转载请注明原文链接:https://www.cnblogs.com/xiaoguo-java/p/14859568.html
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 上周热点回顾(2.17-2.23)
· 如何使用 Uni-app 实现视频聊天(源码,支持安卓、iOS)
· spring官宣接入deepseek,真的太香了~