Java并发总结一 :1~2
来源:互联网 发布:斯提亚在淘宝的正品店 编辑:程序博客网 时间:2024/05/16 18:40
1.并发多面性
多处理器的web服务器:为每个请求分配一个线程。
单处理器:用户界面,创建单独线程来响应用户输入
仿真:动画中,解决大量的独立动作
2.基本线程机制
底层机制:切分CPU时间,每个线程都觉得自己一直在占用CPU时间
2.1 定义任务
继承runnable接口,并覆盖run方法
public class MyTask implements Runnable{ @Override public void run() { for (int i = 0; i < 3; i++) { System.out.println(Thread.currentThread().getId()); Thread.yield(); } }}
2.2 使用Thread类创建线程
//使用构造方法传入2.1中任务Thread thread=new Thread(new MyTask());
2.3 使用Executors类的静态方法创建线程
ExecutorService service1=Executors.newCachedThreadPool();ExecutorService service2=Executors.newFixedThreadPool(45);ExecutorService service3=Executors.newSingleThreadExecutor();ExecutorService service4=Executors.newScheduledThreadPool(56);
- newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。 - newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。 - newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。 - newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。
线程池的作用:
限制系统中执行线程的数量 ,可以自动或手动设置线程数量,达到运行的最佳效果;
少了浪费了系统资源,多了造成系统拥挤效率不高。用线程池控制线程数量,其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有等待进程,线程池的这一资源处于等待。当一个新任务需要运行时,如果线程池中有等待的工作线程,就可以开始运行了;否则进入等待队列。
2.4 从任务中产生返回值
继承Callable接口。
class MyReturnTask implements Callable<String> { @Override public String call() throws Exception { return "some...strings"; }}
使用ExecutorService实例的submit()方法调用它。
ExecutorService e = Executors.newFixedThreadPool(10);Future<String> future = e.submit(new MyReturnTask());while (true) { if (future.isDone()) { System.out.println(future.get()); break; }}e.shutdown();
submit()方法返回一个Future,isDone()会检查Future是否完成。
你也可以直接调用Future的get方法,它具有阻塞作用,知道完成才会获取值。
2.5 线程休眠
第一种方式:使用Thread.sleep(n) —>可读性较差
Thread.sleep(1000);
第二种方式:使用TimeUnit类—>推荐
TimeUnit.SECONDS.sleep(3);//休眠3秒TimeUnit.MINUTES.sleep(5);//休眠5分钟TimeUnit.DAYS.sleep(8);//休眠8天
2.6 优先级
public class MyTask implements Runnable { @Override public void run() { Thread.currentThread().setPriority(Thread.MAX_PRIORITY);//最高优先级 Thread.currentThread().setPriority(Thread.MIN_PRIORITY);//最低优先级 Thread.currentThread().setPriority(Thread.NORM_PRIORITY);//中等优先级 Thread.currentThread().setPriority(8);//优先级为8 Thread.currentThread().getPriority();// 获取 当前优先级 }}
2.7 让步
建议具有相同优先级的其他程序可以运行。
Thread.yield();
2.8 后台线程
使用Thread.setDeamon
如下,主线程退出后,后台线程也会退出,如果去掉thread.setDaemon(true)这句时,该线程将会一直循环打印下去…
public class RunTest { public static void main(String[] args) throws InterruptedException { Thread thread = new Thread(new MyDeamonTask()); thread.setDaemon(true);//尝试下去掉这句 thread.start(); TimeUnit.MILLISECONDS.sleep(15); //主线程退出 }}class MyDeamonTask implements Runnable { @Override public void run() { while (true) { System.out.println(Thread.currentThread()); } }}
使用ThreadFactory
class MyFactory implements ThreadFactory { @Override public Thread newThread(Runnable r) { Thread t = new Thread(r); t.setDaemon(true);//此处也可以对进程进行其他设置,比如优先级 return t; }}public class RunTest { public static void main(String[] args) throws InterruptedException { ExecutorService service = Executors.newCachedThreadPool(new MyFactory()); service.execute(new Runnable() { @Override public void run() { while (true){ System.out.println(Thread.currentThread().getId()+"deamon"); } } }); TimeUnit.MILLISECONDS.sleep(123); //主线程退出 }}
后台线程派生出来的线程也是后台线程
略
2.9直接使用Thread创建线程和任务
继承Thread类并覆盖run方法即可
class MyThread extends Thread{ @Override public void run() { //do }}
2.10 加入一个线程
public class RunTest { public static void main(String[] args) throws InterruptedException { Thread t = new MyThread(); t.start(); t.join();//main线程被挂起,直到t线程结束 System.out.println("main..." ); }}class MyThread extends Thread { @Override public void run() { for (int i = 0; i < 10; i++) { System.out.println(i); try { TimeUnit.MILLISECONDS.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } } }}
上述代码执行 结果如下:
如果去掉t.join(),会发现main线程将不会最后执行!
2.11 线程的异常
代码如下:主线程将不会捕获到MyThread中出现的异常
public class RunTest { public static void main(String[] args) throws InterruptedException { Thread t = new MyThread(); try{ t.start(); }catch (Exception e){ System.out.println("catch it"); } }}class MyThread extends Thread { @Override public void run() { throw new RuntimeException("exception~~~"); }}
使用setUncaughtExceptionHandler,修改为:
public class RunTest { public static void main(String[] args) throws InterruptedException { Thread t = new MyThread(); t.setUncaughtExceptionHandler(new Thread.UncaughtExceptionHandler() { @Override public void uncaughtException(Thread t, Throwable e) { System.out.println("catch it..."); } }); t.start(); }}
0 0
- Java并发总结一 :1~2
- Java 并发总结(一)
- Java并发编程总结一
- Java并发总结1
- Java并发总结(一):线程基础
- Java并发总结(一):线程基础
- JAVA并发处理经验(一)多线程总结
- Java并发总结一 :3~4
- Java常用并发容器总结(一)
- Java并发编程重要总结(一)
- 并发总结一
- Java并发总结(一): 线程的介绍及创建
- Java多线程与并发编程总结(一)
- 《Java并发编程实战》- 个人阅读总结(一)
- java高并发程序设计总结一:走进并行世界
- java并发编程实战总结2
- 10 Java并发编程1总结
- java并发编程总结(1)
- 利用select/poll监听多个设备详解
- Linux locate --快速搜索档案系统内是否有指定档案 2013年7月3日
- 决策树中基本概念——香农熵
- Unity编辑器之inspector处理
- [软件人生]关于认知,能力的思考——中国城市里的无知现象片段补充之一
- Java并发总结一 :1~2
- applePay 项目的配置和集成
- c++构造函数
- PCA (主成分分析)详解 (写给初学者) 结合matlab
- 30个实用的Linux find命令示例
- Linux make --强大的编译工具
- iOS开发~iOS9状态栏颜色设置
- C++第二次实验_循环
- ssh生成随机数字验证码操作步骤