-
Notifications
You must be signed in to change notification settings - Fork 0
feiniaoqy/JavaThreadDemo
Folders and files
| Name | Name | Last commit message | Last commit date | |
|---|---|---|---|---|
Repository files navigation
# JavaThreadDemo 所引用的博客有: http://spidermanzy.iteye.com/blog/1734872 ---这是从一篇博客复制的,对Java多线程介绍得特别全 http://blog.csdn.net/sd0902/article/details/8395677--这篇主要是针对线程池的介绍 //=========================以下是自己的简略总结的知识点======================================== 1、线程创建的两种方式: 实现Runnable接口和继承Tread //返回该线程的状态 getState(); //中断线程 interrupt(); //测试当前线程是否已经中断 interrupted(); //测试线程是否处于活动状态 isAlive(); //测试该线程是否为守护线程 isDaemon(); //等待该线程终止 join(); //改变线程名称,使之与参数 name 相同 setName("普通线程"); //将该线程标记为守护线程或用户线程 setDaemon(true); //更改线程的优先级 setPriority(1);//1-10之间 //暂停当前正在执行的线程对象,并执行其他线程s yield(); 新建状态(new) 当一个线程对象创建后,处于新建状态,在这种状态下,线程对象还只是一个对象, 没有成为一条独立执行的线索,也不可能被线程调度程序调度 准备状态(runnable) 处于新建状态下的线程被start()调用后进入准备状态,这个状态随时可能被线程调度程序调度, 获取CPU执行时间,线程一旦进入准备状态不能回到新建状态 运行状态(running) 一旦处于准备状态的线程获取CPU时间,就进入了执行状态, 线程随时可能被调度程序调度到准备状态, 于某种必要的条件或者由于运行特定的方法,可能会进入等待/阻塞状态 等待阻塞状态(blocked) 因为某种原因放弃了CPU使用权,暂时停止运行 直到线程进入就绪状态,才有机会转入运行状态 阻塞分为三种 等待阻塞 运行的线程执行wait()方法,JVM会把该线程放入等待池中 同步阻塞 运行线程在获取对象的同步锁时,若该同步锁被别的线程占用,JVM会把该线程放入锁池中 其他阻塞 运行线程执行了sheep()或者join()或者发生了I/O请求时JVM会将线程置为阻塞状态 当sheep()超时,join()等待线程终止或者超时,I/O处理完毕,线程重新进入就绪状态 死亡状态(dead): 当线程的run方法正确执行完毕或者由于发生了异常而终止了执行时, 线程就进入了死亡状态,进入死亡状态下的线程不能再被启动 2、线程之间是异步的,要实现同步,必须对要同步的代码块或者方法加锁 3、线程之间的通信:则主要采用"共享变量"和"管道流"这两种方法 方法一 通过访问共享变量的方式(注:需要处理同步问题) 方法二 通过管道流 4、线程池的优点: 1.减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。 2.可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而使服务器死机(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。 5、线程池的实现 在JavaAPI中的Executors类提供了一些静态工厂,生成一些常用的线程池: 1. newSingleThreadExecutor 创建一个单线程的线程池。这个线程池只有一个线程在工作,也就是相当于单线程串行执行所有任务。如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。此线程池保证所有任务的执行顺序按照任务的提交顺序执行。 2.newFixedThreadPool 创建固定大小的线程池。每次提交一个任务就创建一个线程,直到线程达到线程池的最大大小。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。 3. newCachedThreadPool 创建一个可缓存的线程池。如果线程池的大小超过了处理任务所需要的线程, 那么就会回收部分空闲(60秒不执行任务)的线程,当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。 4.newScheduledThreadPool 创建一个大小无限的线程池。此线程池支持定时以及周期性执行任务的需求。 另外ScheduledThreadPoolExecutor类也可以实现 6、重点是ThreadPoolExecutor类: 构造方法: ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) 参数说明: corePoolSize - 池中所保存的线程数,包括空闲线程。 maximumPoolSize - 池中允许的最大线程数。 keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。 unit - keepAliveTime 参数的时间单位。 workQueue - 执行前用于保持任务的队列。此队列仅由保持 execute 方法提交的 Runnable 任务。 这里有三种方式: 直接提交。也即SynchronousQueue。工作队列的默认选项是 SynchronousQueue,它将 任务直接提交给线程而不保持它们。在此,如果不存在可用于立即运行任务的线程,则试图把任务加入队列将失败, 因此会构造一个新的线程。此策略可以避免在处理可能具有内部依赖性的请求集时出现锁。直接提交通常要求无界 maximumPoolSizes 以避免拒绝新提交的任务。当命令以超过队列所能处理的平均数连续到达时,此策略 允许无界线程具有增长的可能性。 无界队列。即LinkedBlockingQueue。使用无界队列(例如,不具有预定义容量的 LinkedBlockingQueue) 将导致在所有 corePoolSize 线程都忙时新任务在队列中等待。这样,创建的线程就不会超过 corePoolSize。 (因此,maximumPoolSize的值也就无效了。)当每个任务完全独立于其他任务,即任务执行互不影响时, 适合于使用无界队列;例如,在 Web页服务器中。这种排队可用于处理瞬态突发请求,当命令以超过队列所能处 理的平均数连续到达时,此策略允许无界线程具有增长的可能性。 有界队列。ArrayBlockingQueue。当使用有限的 maximumPoolSizes时,有界队列(如 ArrayBlockingQueue)有助 于防止资源耗尽,但是可能较难调整和控制。队列大小和最大池大小可能需要相互折衷:使用大型队列和小型池可以最大限 度地降低 CPU 使用率、操作系统资源和上下文切换开销,但是可能导致人工降低吞吐量。如果任务频繁阻塞(例如,如果 它们是 I/O边界),则系统可能为超过您许可的更多线程安排时间。使用小型队列通常要求较大的池大小,CPU使用率较高, 但是可能遇到不可接受的调度开销,这样也会降低吞吐量。 threadFactory - 执行程序创建新线程时使用的工厂。 handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。 在ThreadPoolExecutor中已经默认包含了4中策略: CallerRunsPolicy:线程调用运行该任务的 execute 本身。此策略提供简单的反馈控制机制,能够减缓新任务的提交速度。 AbortPolicy:处理程序遭到拒绝将抛出运行时RejectedExecutionException DiscardPolicy:不能执行的任务将被删除 DiscardOldestPolicy:如果执行程序尚未关闭,则位于工作队列头部的任务将被删除,然后重试执行程序(如果再次失败,则重复此过程) //=========================以上是自己的简略总结的知识点========================================
About
No description, website, or topics provided.
Resources
Stars
Watchers
Forks
Releases
No releases published
Packages 0
No packages published