今天复习熟悉了Java并发的一些概念。
程序:系统要完成的一个任务,就是一个程序;
进程:每个运行中的程序就是一个进程,Windows任务管理器上可以看到每一个进程,Linux下使用ps –e命令可以查看当前运行的所有进程;
线程:每个运行的程序(进程)内部可能会包含多个顺序执行流,每个执行流就可以看做线程。
1. 进程的特性:
1) 独立性:进程是系统中独立存在的实体,它可以拥有自己独立的资源,每个进程都拥有自己私有的地址空间,其他进程不能访问这个进程空间内的数据。
2) 动态性:进程与程序的区别在于,程序是静态的,进程是动态的,程序只是一个静态的指令集合,而进程是一个正在系统中运行的指令集合,有生命周期等时间概念;
3) 并发性:进程之间,可以交替执行,提高程序执行效率。
2. 线程是一个顺序执行流,它是进程的组成部分,一个进程可以有多个线程,线程的特点如下:
1) 进程之间不能共享内存,但线程可以共享同一片内存中的数据;
2) 系统创建进程需要为该进程重新分配系统资源,但创建线程的代价很小,因此用多线程实现多任务并发比多进程实现并发的效率高;
3) java语言内置多线程功能支持,而不是单纯的作为底层操作系统的调度方式,Java封装了操作系统底层的调度,屏蔽了不同操作系统调度之间的差异。、
3. 守护线程:
守护线程是指用户程序在运行的时后台提供的一种通用服务的线程,比如用于垃圾回收的垃圾回收线程。这类线程并不是用户线程不可或缺的部分,只是用于提供服务的”服务线程”。基于这个特点,当虚拟机中的用户线程全部退出运行时,守护线程没有服务的对象后,JVM也就退出了。JDK源码中是这样解释守护线程的:
* Marks this thread as either a {@linkplain #isDaemon daemon} thread or a user thread. The Java Virtual Machine exits when the only threads running are all daemon threads.
4. 线程的创建方法
有两种创建线程的方法:一是实现Runnable接口,然后将它传递给Thread的构造函数,创建一个Thread对象;二是直接继承Thread类。
5. 线程的生命周期
当我们在Java程序中新建一个线程时,它的状态是New。当我们调用线程的start()方法时,状态被改变为Runnable。线程调度器会为Runnable线程池中的线程分配CPU时间并将它们的状态改变为Running,其他的线程状态还有Waiting(休眠时),Blocked(系统调用阻塞式IO方法时)和Dead(run或call执行结束、抛出异常等)。
6. 线程优先级
每一个线程都有优先级,一般来说,高优先级的线程在运行时会具有优先权,但这依赖于线程调度的实现,这个实现是和操作系统相关的(OS dependent)。我们可以定义线程的优先级,但是这并不能保证高优先级的线程会在低优先级的线程前执行。线程优先级是一个int变量(从1-10),1代表最低优先级,10代表最高优先级。但Win7系统的优先级只有7个级别,并不是和Java中的优先级一一对应的,因此,Windows下的Java程序一般只使用MAX_PRIORITY、NORM_PRIORITY和MIN_PRIORITY三种级别的优先级。
7. 线程调度器(Thread Scheduler)和时间分片(Time Slicing )
线程调度器是一个操作系统服务,它负责为Runnable状态的线程分配CPU时间。一旦我们创建一个线程并启动它,它的执行便依赖于线程调度器的实现。时间分片是指将可用的CPU时间分配给可用的Runnable线程的过程。分配CPU时间可以基于线程优先级或者线程等待的时间。线程调度并不受到Java虚拟机控制,所以由应用程序来控制它是更好的选择(也就是说不要让你的程序依赖于线程的优先级)。
小感:
想到了在学校做的一个功能,用Websocket实现的网页即时通讯,其实,服务器接收客户端消息,转发消息,存储消息就可以用多线程技术实现来提高效率。客户端发来的消息在后台用Map对象存储,开辟多个线程,一个线程用以保存数据到Map对象,一个用以转发消息给在线的用户,一个用以在空闲时将数据持久化存储到数据库,一个用以监听客户端发送过来的消息,这样就能大大提高消息的转发、存储效率。当然,这里面可能牵涉到对Map对象的读写分离,可以用锁机制来保证读写一致性(下次详细探讨下Java并发中锁的实现)。
版权声明:本文为博主原创文章,未经博主允许不得转载。