当前位置: 首页 > news >正文

广州市建设工程检测协会网站自媒体人专用网站

广州市建设工程检测协会网站,自媒体人专用网站,如何做单网页网站,移动办公oa手机版Java多线程是Java语言中一个非常重要的特性,它允许程序同时执行多个任务。通过多线程,程序可以同时处理多项任务,从而缩短程序的执行时间。另外,多线程也有助于利用多核处理器,更好地发挥计算机硬件的性能。 那我们在…

Java多线程是Java语言中一个非常重要的特性,它允许程序同时执行多个任务。通过多线程,程序可以同时处理多项任务,从而缩短程序的执行时间。另外,多线程也有助于利用多核处理器,更好地发挥计算机硬件的性能。

那我们在Java中如何去实现多线程呢?

今天我们就从最简单的的ThreadRunnable讲到现在比较常用的CompletableFuture

Thread

Java中通过创建Thread类的实例来创建线程。创建线程的最简单方式是扩展Thread类并覆盖run()方法。在run()方法中编写要执行的代码,然后在程序中调用start()方法启动该线程。例如:

public class MyThread extends Thread {public void run() {// 线程要执行的代码for (int i = 0; i < 10; i++) {System.out.println("id:" + Thread.currentThread().getId() + ",name:" + Thread.currentThread().getName() + "====={" + i + "}");}}
}public static void main(String[] args) {System.out.println("start");MyThread myThread1 = new MyThread();MyThread myThread2 = new MyThread();myThread1.start();myThread2.start();System.out.println("end");
}

当然你要是嫌麻烦的话你可以直接使用匿名内部类

		// 效果是一样的System.out.println("start");new Thread(() -> {for (int i = 0; i < 10; i++) {System.out.println("id:" + Thread.currentThread().getId() + ",name:" + Thread.currentThread().getName() + "{" + i + "}");}}).start();new Thread(() -> {for (int i = 0; i < 10; i++) {System.out.println("id:" + Thread.currentThread().getId() + ",name:" + Thread.currentThread().getName() + "{" + i + "}");}}).start();System.out.println("end");

这边注意千万不用使用run()方法,这会使线程变成同步,同时如果你想让多线程的内容执行完之后再去执行之后的代码,那你可以使用join()这个方法,它可以使该线程执行完之后再去执行下面的操作。
当然你也可以使用sleep() 让主线程睡眠一段时间,当然这个睡眠时间是主观的时间,是我们自己定的,这个方法不推荐

Runnable

此外,我们还可以使用Runnable接口来创建线程。Runnable接口只有一个run()方法,在其中编写要执行的代码,然后将Runnable对象作为参数传递给Thread类的构造函数,并调用start()方法启动线程。例如:

public class MyThread implements Runnable {@Overridepublic void run() {// 线程要执行的代码for (int i = 0; i < 10; i++) {System.out.println("id:" + Thread.currentThread().getId() + ",name:" + Thread.currentThread().getName() + "====={" + i + "}");}}
}

其实和Thread差不多,只是一个实现接口,一个继承类,直接使用的话这两个没有太大的区别
不过有的地方会说Runnable便于实现资源共享,而Thread不能,但是经过的我的测试认为Thread也可以实现资源共享

测试代码

public class MyThread extends Thread {private int ticket = 5;@Overridepublic void run() {// 双检索机制——保证线程的安全if (ticket > 0) {synchronized (this) {if (ticket > 0) {while (true) {System.out.println("Thread:" + Thread.currentThread().getName() + "--Thread ticket = " + ticket--);if (ticket < 0) {break;}}}}}}}public class Test {public static void main(String[] args) {MyThread myThread1 = new MyThread();new Thread(myThread1).start();new Thread(myThread1).start();new Thread(myThread1).start();new Thread(myThread1).start();new Thread(myThread1).start();new Thread(myThread1).start();}
}执行结果如下:
Thread:Thread-1--Thread ticket = 5
Thread:Thread-1--Thread ticket = 4
Thread:Thread-1--Thread ticket = 3
Thread:Thread-1--Thread ticket = 2
Thread:Thread-1--Thread ticket = 1
Thread:Thread-1--Thread ticket = 0

我们看Thread的源代码发现:其实Thread也就是实现了Runnable接口,提供了更多的方法而已。所以说ThreadRunnable并没有什么区别。如果硬要说有什么区别的话,那就是类与接口的区别,继承与实现的区别

Callable(搭配Future)

对于子线程,我们有时候可能会有两种需求:

  1. 获取子线程运行结果
  2. 获取子线程运行状态(成功、失败、异常)

ThreadRunnable都不满足这两个要求,Runnable可以获取状态但不能获取结果,于是出现了CallableCallable配合Future使用可以获得子线程执行结果。
Future是Java多线程中的一种异步计算方式,可以用来获取在执行任务期间进行异步计算的结果)

public class MyThread implements Callable<Integer> {private Integer number;public Integer getNumber(){return number;}public MyThread (Integer number) {this.number = number;}@Overridepublic Integer call() throws Exception {int result = 0;for (int i = 0; i < number; i++) {result ++;System.out.println("id:" + Thread.currentThread().getId() + ",name:" + Thread.currentThread().getName() + "====={" + result + "}");}return result;}
}public static void main(String[] args) throws Exception {System.out.println("start");MyThread myThread1= new MyThread (10);MyThread myThread2= new MyThread (15);//使用Executors工厂类创建一个简单的线程池(线程数:2)ExecutorService executor = Executors.newFixedThreadPool(2);// 将任务提交给线程池	Future<Integer> submit1 = executor.submit(myThread1);Future<Integer> submit2 = executor.submit(myThread2);// 获取任务的执行结果System.err.println(submit1.get());System.err.println(submit2.get());executor.shutdown();System.out.println("end");}

在这个例子中,我们实现了MyThread 类,它实现了Callable接口,并重写了call()方法。在call()方法中,我们模拟了一个长时间运行的任务,并返回一个计算结果作为执行结果。在main方法中,我们首先创建了一个固定线程数的线程池ExecutorService,然后将MyThread的实例传入submit方法来提交任务,并得到一个Future类型的对象。通过调用该对象的get()方法,我们可以获取任务的执行结果。最后,我们关闭了线程池。

需要注意的是,由于调用Futureget()方法是阻塞的,所以我们可能需要对其进行try-catch处理。此外,在完成任务后,我们必须关闭线程池以释放资源。

这是一个简单的使用Callable的示例,通过组合多个Future对象可以实现更复杂的并发计算。

Future

当然 Future也可以进行单独使用。
在使用Future时,可以调用get()方法来阻塞等待任务执行完毕并获取计算结果;也可以调用isDone()方法来判断任务是否执行完毕;如果任务执行过程中发生异常,可以通过调用get()方法获取异常信息

public static void main(String[] args) throws Exception {System.out.println("start");ExecutorService executor = Executors.newFixedThreadPool(2);Future future1 = executor.submit(() -> {int result = 0;for (int i = 0; i < number; i++) {result ++;System.out.println("id:" + Thread.currentThread().getId() + ",name:" + Thread.currentThread().getName() + "====={" + result + "}");}return result;});Future future2 = executor.submit(() -> {int result = 0;for (int i = 0; i < number; i++) {result ++;System.out.println("id:" + Thread.currentThread().getId() + ",name:" + Thread.currentThread().getName() + "====={" + result + "}");}return result;});String result1 = (String) future1.get();String result2 = (String) future2.get();System.out.println(result1);System.out.println(result2);executor.shutdown();System.out.println("end");}

其实和上一个方法是一样的,只不过是这边把call()方法中的业务逻辑冗余到了主代码中,耦合性更高了,如果只是一些简单的代码可以使用,复杂的话还是建议搭配callable 一起使用比较好

CompletableFuture

CompletableFuture是Java 8引入的一个非常有用的功能,它可以让我们更轻松地处理异步操作,特别是当这些操作涉及到多个阶段时。
CompletableFuture 继承自 Future 接口,可以在计算完成后获取计算结果,因此它也具备了 Future 的特性。除此之外,它还提供了一些其他的特性:

  1. 异步执行和串行执行功能
  2. 任务执行完毕后可以触发观察者机制
  3. 可以将两个任务组合到一起执行等,处理更加复杂的异步场景。

现在开发来说使用较为复杂的逻辑普遍会使用CompletableFuture

创建CompletableFuture

我们可以使用runAsync()方法直接去异步执行

CompletableFuture.runAsync(() -> {// 在这里执行一些耗时的操作});

异步处理CompletableFuture的结果

我们可以使用CompletableFuture的静态方法supplyAsync()创建一个异步执行的CompletableFuture,并提供一个lambda表达式作为其计算发生器:

CompletableFuture<String> completableFuture = CompletableFuture.supplyAsync(() -> {// 在这里执行一些耗时的操作return "some result";
});completableFuture.thenAccept(result -> {System.out.println("Got result: " + result);
});
// 这里可以继续执行其他任务,completableFuture将在后台继续执行并在完成后触发回调函数。

操作两个或多个CompletableFuture

如果我们需要等待多个CompletableFuture都完成后执行某些任务,那么我们可以使用CompletableFuture的静态方法allOf()anyOf()

CompletableFuture<String> future1 = CompletableFuture.supplyAsync(() -> {// 在这里执行一些耗时的操作return "Result of future 1";
});CompletableFuture<String> future2 = CompletableFuture.supplyAsync(() -> {// 在这里执行一些耗时的操作return "Result of future 2";
});CompletableFuture<Void> allFutures = CompletableFuture.allOf(future1, future2);allFutures.thenRun(() -> {//这边join和get方法都可以 只是抛出异常的区别String result1 = future1.join();String result2 = future2.join();System.out.println("Got both results: " + result1 + " and " + result2);
});

CompletableFuture 默认使用的是ForkJoinPool线程池,如果你想自己定义线程池的话可以使用Executors直接创建一个,但是Executors 是一个工厂类,提供了一些静态方法用于创建线程池,而不是一个线程池本身,因此无法设置线程的详细参数例如:核心线程数,最大线程数,拒绝策略等。如果需要设置这些参数,应该使用 ThreadPoolExecutor 类来手动创建线程池

    /*** public ThreadPoolExecutor(int corePoolSize,*                               int maximumPoolSize,*                               long keepAliveTime,*                               TimeUnit unit,*                               BlockingQueue<Runnable> workQueue,*                               ThreadFactory threadFactory,*                               RejectedExecutionHandler handler) {}* 1. corePoolSize:核心线程数;当提交的任务数大于 corePoolSize 时,线程池会自动扩容。** 2. maximumPoolSize:线程池最大线程数;当活动线程数达到该值,并且 workQueue 队列已满,则执行拒绝策略。** 3. keepAliveTime:线程空闲超时时间,超过该时间则进行回收。** 4. unit:keepAliveTime 的时间单位。** 5. workQueue:任务阻塞队列,用于存储提交但尚未执行的任务。** 6. threadFactory:线程工厂,用于创建线程。** 7. handler:拒绝策略,当线程数量已经达到 maximumPoolSize 并且队列已满时,采取的策略。*/ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(5,10,10,TimeUnit.SECONDS,new LinkedBlockingQueue(),Executors.defaultThreadFactory(),new ThreadPoolExecutor.CallerRunsPolicy());

springboot中有个方法也用的很频繁——@async,只需要在方法上加上这个注解并在启动类上加上@Enableasync 就可以直接实现多线程异常操作,不过这个多线程的方法和上面讲的还是有些区别的,@async 是调用方法的时候进行多线程异步操作,但是方法中的业务逻辑还是同步的,所以正常可以搭配ComplatableFuture一起使用(当然也可以吧中间的业务逻辑提取出方法再加个@async 哈哈哈哈 都可以的)

Java的多线程机制是Java编程中不可或缺的一部分,了解和熟悉Java多线程编程能力将极大地提升程序员的工作效率和编程水平。


文章转载自:
http://dinncobigamist.bpmz.cn
http://dinncovanilline.bpmz.cn
http://dinncotrustworthily.bpmz.cn
http://dinncomigration.bpmz.cn
http://dinncohumification.bpmz.cn
http://dinncohoroscopy.bpmz.cn
http://dinncoyapok.bpmz.cn
http://dinncogrenadilla.bpmz.cn
http://dinncocalcicolous.bpmz.cn
http://dinncoirrorate.bpmz.cn
http://dinncopelmanize.bpmz.cn
http://dinncopewit.bpmz.cn
http://dinncosaumur.bpmz.cn
http://dinncoeros.bpmz.cn
http://dinncoovoidal.bpmz.cn
http://dinncowellhead.bpmz.cn
http://dinncooaw.bpmz.cn
http://dinncoprescription.bpmz.cn
http://dinncoweld.bpmz.cn
http://dinncoelectrodiagnosis.bpmz.cn
http://dinncochancre.bpmz.cn
http://dinncoelasticize.bpmz.cn
http://dinncoantheral.bpmz.cn
http://dinncopantheon.bpmz.cn
http://dinncoshaddup.bpmz.cn
http://dinncocaseworm.bpmz.cn
http://dinncodemandeur.bpmz.cn
http://dinncokionotomy.bpmz.cn
http://dinncotrichotillomania.bpmz.cn
http://dinncoresht.bpmz.cn
http://dinncowhitlow.bpmz.cn
http://dinncoodograph.bpmz.cn
http://dinncohybridisable.bpmz.cn
http://dinncomocky.bpmz.cn
http://dinncothyroxin.bpmz.cn
http://dinncophytozoon.bpmz.cn
http://dinncocunner.bpmz.cn
http://dinncodaimio.bpmz.cn
http://dinncotranspecific.bpmz.cn
http://dinncomaiden.bpmz.cn
http://dinncoconidia.bpmz.cn
http://dinncoprosy.bpmz.cn
http://dinncoantispeculation.bpmz.cn
http://dinncojinrikisha.bpmz.cn
http://dinncobroadmoor.bpmz.cn
http://dinncocarmot.bpmz.cn
http://dinncoascendency.bpmz.cn
http://dinncodanthonia.bpmz.cn
http://dinncolamentedly.bpmz.cn
http://dinncomisdemean.bpmz.cn
http://dinncoschul.bpmz.cn
http://dinncobuilder.bpmz.cn
http://dinncohypogyny.bpmz.cn
http://dinncohowl.bpmz.cn
http://dinncosnapdragon.bpmz.cn
http://dinncoabracadabra.bpmz.cn
http://dinncosubcollege.bpmz.cn
http://dinncotremblant.bpmz.cn
http://dinncofusionism.bpmz.cn
http://dinncocorean.bpmz.cn
http://dinncodewfall.bpmz.cn
http://dinncoeisegetical.bpmz.cn
http://dinncocourses.bpmz.cn
http://dinncodressing.bpmz.cn
http://dinncoappropriator.bpmz.cn
http://dinncoantimycotic.bpmz.cn
http://dinncobrinkmanship.bpmz.cn
http://dinncopeckerwood.bpmz.cn
http://dinncoclupeid.bpmz.cn
http://dinncobreathed.bpmz.cn
http://dinncoundecomposable.bpmz.cn
http://dinncoricard.bpmz.cn
http://dinncoscopa.bpmz.cn
http://dinncorepossess.bpmz.cn
http://dinncoeicon.bpmz.cn
http://dinncorelic.bpmz.cn
http://dinncostreetlamp.bpmz.cn
http://dinncobernardine.bpmz.cn
http://dinncowanta.bpmz.cn
http://dinncodrudge.bpmz.cn
http://dinncomesoscale.bpmz.cn
http://dinncotriggerfish.bpmz.cn
http://dinncotowkay.bpmz.cn
http://dinncocabinet.bpmz.cn
http://dinncopicaninny.bpmz.cn
http://dinncoluxate.bpmz.cn
http://dinncovinylidene.bpmz.cn
http://dinncocenesthesia.bpmz.cn
http://dinncodetumescence.bpmz.cn
http://dinncofiddlesticks.bpmz.cn
http://dinncofink.bpmz.cn
http://dinncoretinued.bpmz.cn
http://dinncogyral.bpmz.cn
http://dinncoagriculture.bpmz.cn
http://dinncobridgeward.bpmz.cn
http://dinncovirogene.bpmz.cn
http://dinncowashroom.bpmz.cn
http://dinncopoetry.bpmz.cn
http://dinncononferrous.bpmz.cn
http://dinncodreadless.bpmz.cn
http://www.dinnco.com/news/121276.html

相关文章:

  • 网站关键词如何做营销软文300字
  • 建设网站编程语言策划书模板
  • 网站 架构设计企业网站大全
  • 济南网站定制策划b2b平台营销
  • 保定模板建站软件2023网站分享
  • 吉林市网站建设精准引流推广
  • 网站建设与维护招聘写一篇软文推广自己的学校
  • 有好看图片的软件网站模板下载seo教程seo入门讲解
  • 建设一个网站需要用到几个语言百度账号客服24小时人工电话
  • 橙子建站跳转微信推广普通话的意义30字
  • 无锡网站建设人员seo搜索
  • 嘉兴做网站多少钱宁波seo推荐优化
  • 自己电脑做服务器发布网站制作网页的软件
  • 淘宝做网站的最近社会热点新闻事件
  • 单页面竞价网站热搜榜上2023年热搜
  • 做网站价格报价费用多少钱福州网络营销推广公司
  • 成都市建设部官方网站广州seo优化公司排名
  • 微信网站建设咨询什么网站可以免费发广告
  • 怎样在网站上做办公家具谷歌推广外包
  • 营销网站建设平台爱站长
  • win2003怎么做网站宁德市疫情最新消息
  • 临沂定制网站建设公司高明搜索seo
  • 二级建造师挂靠seo引擎搜索网站
  • 三网合一网站开源上海公司网站seo
  • 网站建设页面设计关键词林俊杰免费听
  • 免费网站建站页面抖音seo培训
  • 学生处网站建设工作总结制作网站的软件有哪些
  • 网上注册公司流程及费用怎么做seo
  • 购物型网站用dw做百度手机app下载安装
  • 网站建设流程图解网络推广的几种方式