多线程之二
2022/4/3 6:21:22
本文主要是介绍多线程之二,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
线程通信
/** * 两个线程交替打印1-100之间的数字 */ public class ThreadTest3 { public static void main(String[] args) { Demo04 demo04 = new Demo04(); Thread t1 = new Thread(demo04); Thread t2 = new Thread(demo04); t1.setName("线程一"); t2.setName("线程二"); t1.start(); t2.start(); } } class Demo04 implements Runnable{ private static int i=1; @Override public void run() { while (true){ synchronized (this){ //唤醒所有线程,首次执行时无效果 notifyAll(); if (i<=100){ System.out.println(Thread.currentThread().getName()+":"+i); i++; try { //使当前线程沉睡。可以被notifyAll()和notify()唤醒 wait(); } catch (InterruptedException e) { e.printStackTrace(); } }else { break; } } } } }
wait() 与 notify() 和 notifyAll()
- wait():令当前线程挂起并放弃CPU、同步资源并等待,使别的线程可访问并修改共享资源,而当 前线程排队等候其他线程调用notify()或notifyAll()方法唤醒,唤醒后等待重新获得对监视器的所有 权后才能继续执行。
- notify():唤醒正在排队等待同步资源的线程中优先级最高者结束等待
- notifyAll ():唤醒正在排队等待资源的所有线程结束等待.
这三个方法只有在synchronized方法或synchronized代码块中才能使用,否则会报
java.lang.IllegalMonitorStateException异常。
面试题:sleep() 和 wait()的异同?
- 相同点:一旦执行方法,都可以使得当前的线程进入阻塞状态。
- 不同点:
- 两个方法声明的位置不同:Thread类中声明sleep() , Object类中声明wait()
- 调用的要求不同:sleep()可以在任何需要的场景下调用。 wait()必须使用在同步代码块或同步方法中
- 关于是否释放同步监视器:如果两个方法都使用在同步代码块或同步方法中,sleep()不会释放锁,wait()会释放锁。
JDK5.0新增的线程创建方式
实现Callable接口
-
Callable接口
-
相比run()方法,可以有返回值
-
方法可以抛出异常
-
支持泛型的返回值
-
需要借助FutureTask类,比如获取返回结果
-
-
Future接口
- 可以对具体Runnable、Callable任务的执行结果进行取消、查询是 否完成、获取结果等。
- FutrueTask是Futrue接口的唯一的实现类
- FutureTask 同时实现了Runnable, Future接口。它既可以作为Runnable被线程执行,又可以作为Future得到Callable的返回值
public class ThreadTest4 { public static void main(String[] args) throws ExecutionException, InterruptedException { Demo05 demo05 = new Demo05(); FutureTask futureTask = new FutureTask(demo05); new Thread(futureTask).start(); Object o = futureTask.get(); System.out.println(o); } } class Demo05 implements Callable{ @Override public Object call() throws Exception { int sum =0; for (int i = 1; i <=100 ; i++) { if (i%2==0){ System.out.println(i); sum+=i; } } return sum; } }
线程池
- 背景:经常创建和销毁、使用量特别大的资源,比如并发情况下的线程, 对性能影响很大。
- 思路:提前创建好多个线程,放入线程池中,使用时直接获取,使用完 放回池中。可以避免频繁创建销毁、实现重复利用。类似生活中的公共交 通工具。
好处:
- 提高响应速度(减少了创建新线程的时间)
- 降低资源消耗(重复利用线程池中线程,不需要每次都创建)
- 便于线程管理
- corePoolSize:核心池的大小
- maximumPoolSize:最大线程数
- keepAliveTime:线程没有任务时最多保持多长时间后会终止
- …
实现
- JDK 5.0起提供了线程池相关API:ExecutorService 和 Executors
- ExecutorService:真正的线程池接口。常见子类ThreadPoolExecutor
- Executors:工具类、线程池的工厂类,用于创建并返回不同类型的线程池
public class Pool { public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(10); service.execute(new Demo06()); service.shutdown(); } } class Demo06 implements Runnable{ @Override public void run() { for (int i = 1; i <=100 ; i++) { if (i%2==0){ System.out.println(i); } } } }
这篇关于多线程之二的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-06-26结对编程到底难不难?答案在这里
- 2024-06-19《2023版Java工程师》课程升级公告
- 2024-06-15matplotlib作图不显示3D图,怎么办?
- 2024-06-1503-Loki 日志监控
- 2024-06-1504-让LLM理解知识 -Prompt
- 2024-06-05做软件测试需要懂代码吗?
- 2024-06-0514-ShardingSphere的分布式主键实现
- 2024-06-03为什么以及如何要进行架构设计权衡?
- 2024-05-31全网首发第二弹!软考2024年5月《软件设计师》真题+解析+答案!(11-20题)
- 2024-05-31全网首发!软考2024年5月《软件设计师》真题+解析+答案!(21-30题)