(二) java并发编程--为什么使用多线程
来源:互联网 发布:珠海金山软件招聘 编辑:程序博客网 时间:2024/05/16 10:11
(1.1)计算机硬件
在计算机发展早期,计算机还没有操作系统;自始至终的执行一个程序,这个程序直接访问机器的所有资源。每次只运行一个程序,不能很好的利用稀缺的计算机资源。
(1.2 )操作系统的诞生
操作系统的诞生让多个程序可以同时运行,程序在各自的进程(process)中运行,互相分离,各自独立运行,有操作系统来分配资源,比如内存、文件句柄、安全证书。如果需要的话,进程会通过一些原始的机制互相通信:socket、信号处理(singal handles)、共享内存(shared memory)、信号量(semaphores)和文件。
(1.3)单线程带来的问题
1.3.1)资源利用
有时候需要等待外部操作,比如等待输入和输出,单进程在等待的时候不能进行其他操作,如果在等待的过程中其他程序可以运行就会提高效率。
例如我们去沏茶,首先要烧水,我在烧水的时候可以准备茶壶、茶碗,而不是完全等水烧开了,再去做一些准备工作。其实是更好的利用了“自己”这个资源,不会让空闲下来,这样也会提高效率。
1.3.2)进程之间公平性
单进程,需要一个程序结束后,下一个程序才能进行,类似有“严格的等级制度”,不能很好的共享计算机资源,对系统没有平等的优先级别。
1.3.3)方便
写一些程序,让它们各自自行一个单独任务,要比把所有的程序都放到一个程序更容易理解。就像写代码的时候,把所有的业务逻辑都放到一个方法中一样,不容易理解,也难以修改和扩展。
(1.4)多线程优点
线程是通过异步的方式把工作流程转化为普遍存在的看似”顺序流程“,使程序模拟人类工作和交互变得容易了。另一方面,它们可以把复杂、难以理解的代码转化为直接、简洁的代码,这样更容易读写和维护。
线程在GUI应用程序中是非常有用的,可以用来改进用户接口的响应性,并且在服务器应用中,提高资源的利用率和吞吐率。
上面介绍过,如果一个程序是单线程的,这个处理器在等待一个同步I/O操作完成的时候,仍然是空闲的。在一个多线程程序中,当第一个程序等待I/O结束的同时,另外的一个线程也可以运行,使用使得应用程序遇到I/O阻塞的时候仍然有进展。
(1.4.1)多线程的风险
例如下代码;
packageunsafeThread;/***Created by fang on 2017/11/17.*/public classUnsafeSequenceimplements Runnable{ privateint value; publicint getNext(){ returnvalue++;}public voidrun(){ System.out.println(getNext());} } packageunsafeThread; /*** test for thread*Created by fang on 2017/11/17.*/public classClient{ publicstatic void main(String[]args) { UnsafeSequenceunsafeSequence =new UnsafeSequence(); for(inti=0;i<10000;i++){ Threadthread = newThread(unsafeSequence); thread.start(); } }}
执行结果中可以看出有的数字并未是按照顺序输出,每个线程独立操作,读取这个值,加1,然后再写入新值,因为在操作过程中多个线程交替占用运行时,某个线程读取value值的时候,已经有线程再给value加1,导致value并不是按照次序输出,这就是线程不安全。
活跃度失败
实在并发编程写代码的时候,可能会有这样的风险,可能会因为粗心导致程序无限循环。例如A线程等待一个线程B独占有的资源,B永远不释放这个资源,A将永远等待下去。
(1.5)线程无处在
每一个java应用程序都使用线程。当JVM启动后,它创建一些线程来进行自身的常规管理(垃圾回收、终结处理),以及运行一个main函数的主线程。
AWT和Swing用户接口框架创建线程来管理用户接口事件。
Timer创建执行延迟的任务线程。
组件框架,比如servlet和RMI,会创建线程池,池中线程调用组件方法。
线程安全组件示例
Servlets和javaServer Pages(JSPs)Servlets框架设计目的是,在处理web应用部署,分发来自远程HTTP客户请求这些基础层业务。一个请求到达Server并被分发后,可能通过一个过滤器链到达相应的Servlet或者JSP。每个servlet代表逻辑的一个组件,在访问较大网站中,许多客户可能对相同的servlet的服务请求。servlet的规范规定了一个Servlet必须为多个用户同时调用它做好准备。换句话说,Servlet需要是线程安全的。
即使能够保证一个servlet一次只被一个线程调用,你在建立一个web应用程序时可能仍然要注意线程安全。Servlets通常访问与其他Servlets共享的状态信息,比如程序范围内的对象(Servletcontext对象)或者Session范围内的对象。当一个Servlet访问的对象在Servlets间共享或者请求间共享时,必须对这些对象的访问控制进行适当的协调,因为来自不同线程的多个请求可能同时访问它们。Servlet、JSP和ServletFilter以及那些存储在ServletContext和HttpSession容器中的对象,明显必须是线程安全的。
RMI(Remote Method Invocation)RMI使你能够调用在另外一个JVM上运行的对象方法。当你使用RMI调用一个远程方法时,这个方法的参数被打包成一个比特流,并穿越整个网络到达远程JVM,在那里会被解包并传递给远程方法。
当RMI代码调用了你的远程对象时,这个调用发生在哪一个线程?你并不知道,但绝对不是你创建的那个线程--你的对象被RMI管理的一个线程调用。RMI创建了多少线程?在多个RMI线程中,同一个对象的同一个方法是不是可能同时被调用,所以RMI对象必须是线程安全的。
(1.6)总结
多线程是历史发展的必然,那线程的安全性怎么保障呢?什么是线程的安全性?下一篇线程的安全性。
- (二) java并发编程--为什么使用多线程
- Java并发编程(二)多线程编程
- Java多线程并发编程之二volatile
- java多线程与并发之java并发编程实践(二)
- Java 多线程 并发编程
- java 并发编程 多线程
- Java 多线程 并发编程
- Java 多线程并发编程
- Java 多线程 并发编程
- Java 多线程 并发编程
- Java 多线程 并发编程
- Java 多线程 并发编程
- Java 多线程 并发编程
- Java 多线程 并发编程
- Java 多线程 并发编程
- java多线程 并发编程
- Java 多线程 并发编程
- Java 多线程 并发编程
- 3-Druid单机测试与数据加载方法
- 利用函数实现简单功能
- Java数据类型
- 【BZOJ1251】序列终结者
- 欢迎使用CSDN-markdown编辑器
- (二) java并发编程--为什么使用多线程
- Android 开发中使用硬件加速
- Win10搭建GPU版Keras
- 基本的Sql语句使用
- Git版本控制管理教程(一):介绍
- 电路
- 欢迎使用CSDN-markdown编辑器
- Linux下多进程编程
- 【C++】链表实现约瑟夫环