以下为本人学习笔记,仅供参考:
一、简介
进程:一个程序执行的实例
线程:一个进程可以有多个线程,每个线程完成不同的任务,多个线程同时运行称为并发
进程和线程的区别:每个进程需要系统分配独立的内存地址空间,同一进程中所有线程在同一内存地址空间,共享一块地址资源。
java中的线程指的是两种:java.lang.Thread类的一个实例;线程的执行
二、线程生命周期:新建、就绪、运行、阻塞、死亡
新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread();
就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,随时等待CPU调度执行,并不是说执行了t.start()此线程立即就会执行;
运行状态(Running):当CPU开始调度处于就绪状态的线程时,此时线程才得以真正执行,即进入到运行状态。注:就 绪状态是进入到运行状态的唯一入口,也就是说,线程要想进入运行状态执行,首先必须处于就绪状态中;
阻塞状态(Blocked):处于运行状态中的线程由于某种原因,暂时放弃对CPU的使用权,停止执行,此时进入阻塞状态,直到其进入到就绪状态,才 有机会再次被CPU调用以进入到运行状态。根据阻塞产生的原因不同,阻塞状态又可以分为三种:
1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
PS:创建线程有两张方式:
1、继承Thread类
2、实现Runnable接口,但是Runnable接口中没有start()方法,所以还需要new一个新的Thread线程来启动实现Runnable的子类。
三、进程间通信
传统的进程间通信的方式有大致如下几种:
(1) 管道(PIPE)
(2) 命名管道(FIFO)
(3) 信号量(Semphore)
(4) 消息队列(MessageQueue)
(5) 共享内存(SharedMemory)
(6) Socket
四、线程的同步与锁
1、多线程同步:
防止多个线程访问一个数据对象,对数据造成破坏。
2、锁:
出现锁的目的是保证同步代码在同一时刻只有一个线程在执行,即保障多线程同步的实现
从JVM对两类数据进行协调:1)保存在堆中的实例变量2)保存在方法区中的类变量),这两类数据是被所有线程共享的,对于java虚拟机来说对于实例和类逻辑上是有一个监视器的,java虚拟机为每一个对象和类都关联一个锁。代表任何时候只允许一个线程拥有的特权。线程访问实例变量或者类变量不需锁。
对于锁具体是,当虚拟机装载一个class文件的时候,它就会创建一个java.lang.Class类的实例。当锁住一个对象的时候,实际上锁住的是那个类的Class对象。一个线程可以多次对同一个对象上锁。对于每一个对象,java虚拟机维护一个加锁计数器,线程每获得一次该对象,计数器就加1,每释放一次,计数器就减 1,当计数器值为0时,锁就被完全释放了。
java程序中,只需要使用synchronized块或者synchronized方法就可以标志一个监视区域
3、锁中实现的步骤:
1. 在需要同步的方法的方法签名中加入synchronized关键字。
2. 使用synchronized块对需要进行同步的代码段进行同步。
3. 使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象。
五、线程池
1、为什么要有线程池:
线程池的出现是为了缓解短时间内巨大请求使服务器和内存崩溃-大量并发,线程池起初是参考数据库的线程池,在池中建立连接实例,访问数据库时,从连接池中取连接,操作后归还,有效利用资源,提供系统承受力
2、线程池处理:
线程池处理器ThreadPoolExecutor 类,包括四类构造方法,其中构造器中主要参数有:
corePoolSize:核心池的大小,也可以调用prestartAllCoreThreads()或prestartCoreThread()方法,预创建线程。默认情况下在创建了线程池后,线程池中的线程数为0,当有任务来之后,就会创建一个线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中;
maximumPoolSize:线程池最大线程数
keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止
workQueue:一个阻塞队列,用来存储等待执行的任务,这个参数的选择也很重要,会对线程池的运行过程产生重大影响,一般来说,这里的阻塞队列有三种选择策略:
(深入剖析线程池实现原理):具体实例参考