Java7并发编程--1、线程管理

1.1 简介

       并发和并行从宏观上来讲都是同时处理多路请求的概念。但并发和并行又有区别,并行是指两个或者多个事件在同一时刻发生;而并发是指两个或多个事件在同一时间间隔内发生。

1.2.线程的创建和运行

  • 继承Thread类,并覆盖run()方法。
  • 实现Runnable接口,覆盖run()方法。传入Thread构造器。
1.3.线程信息的获取和设置
      Thread类的一些属性:
  • ID:线程的唯一标识符
  • Name:线程名称
  • Priority:线程优先级,从1 到 10,1是最低级,一般不推荐修改线程的优先级
  • Status:线程的状态.java中有5种状态:
  1. 新建状态(New):新创建了一个线程对象。
  2. 就绪状态(Runnable):线程对象创建后,其他线程调用了该对象的start()方法。该状态的线程位于可运行线程池中,变得可运行,等待获取CPU的使用权。
  3. 运行状态(Running):就绪状态的线程获取了CPU,执行程序代码。
  4. 死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
  5. 阻塞状态(Blocked):阻塞状态是线程因为某种原因放弃CPU使用权,暂时停止运行。直到线程进入就绪状态,才有机会转到运行状态。阻塞的情况分三种:
      (一)等待阻塞:运行的线程执行wait()方法,JVM会把该线程放入等待池中。
      (二)同步阻塞:运行的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则JVM会把该线程放入锁池中。
      (三)其他阻塞:运行的线程执行sleep()或join()方法,或者发出了I/O请求时,JVM会把该线程置为阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
       Thread类的属性存储了线程的所有信息,并且线程的id和status不能手动更改。如果你是实现 Runnable接口,那么可以通过 Thread的静态方法currentThread()来获取Thread对象。


       写一个实例,演示中断机制:



       线程是否休眠,可以通过isInterrupted()来获取线程的中断状态。还可以使用Thread的静态方法interrupted()来判断,interrupted()和isInterrupted()的区别是isInterrupted()不能改变interrupted的值,但interrupted()可以设置interrupted属性为false。也就是说,如果外部设置了中断状态,调用interrupted()的时候返回true,同时会把中断状态清除为false。因为interrupted()是个静态方法,更推荐使用isInterrupted()方法。
1.5.线程中断的控制
       上一个例子中使用的机制,可以使用在线程很容易中断的情况下。但是,若线程实现了复杂的算法并且分布在几个方法中,或者线程里有递归调用的方法,我们可以利用InterruptedException异常。当线程检测到中断的时候,就抛出这个异常,然后在run()方法中捕获并且处理这个异常。
1.6.线程的休眠和恢复
  • 休眠: 使用TimeUnit.SECONDS.sleep(1)是线程休眠1秒; 能让线程让出cpu执行时钟指令,在这个期间线程是不占用资源的,并且不占用cpu时钟的,所以cpu可以去执行其他的任务。TimeUnit.SECONDS.sleep(1) 也是包装了Thread.sleep(ms, ns)方法.
  • 恢复: 等待休眠时间结束后,该线程又拥有了cpu时钟执行权,线程恢复。
       thread的yield()方法,线程让步,让出当前线程的cpu时钟,但是又可能下一次还是让当前线程获得执行权,这个也是和休眠的一个区别。
1.7.等待线程的终止
  在一些情形下,比如需要先初始化一些资源,初始化完成之后,再继续执行。这个时候我们就需要等待线程终止再执行程序的其他任务。可以使用 thread 的 join()方法,等待线程的终止。
1.8.守护线程的创建和运行
       守护线程(daemon) : 这种线程的优先级很低,当守护线程是程序中唯一的线程的时候,守护线程结束后,jvm也就结束了. 因为这种特性,守护线程通常用来作为统一程序中普通线程(也称为用户线程)的服务提供者.它通常是无线循环的,以等待服务请求或则执行线程的任务.因此他们不能做重要的工作,因为不知道守护线程什么时候能获取cpu时钟指令,也有可能随时结束.作为守护线程,要在该线程start前设置setDemo()。isDaemon() : 获取是否是守护线程。
1.9.线程中不可空异常的处理
       在run方法中,不支持抛出异常.所以如果是非运行时异常,则必须要捕获并处理。如果出现了在运行时异常,默认是在控制台打印. 好在java提供了另一种在线程中捕获运行时异常的一种机制.
  • class MyExHander implements UncaughtExceptionHandler类
  • 在线程start前设置异常处理器thread.setUncaughtExceptionHandler(new MyExHander());设置未捕获异常处理器。
        jvm调用异常处理器的顺序: 线程对象设置的 –> 线程组(ThreadGroup的) –> 最后是上面讲的默认的异常处理器。
1.10.线程局部变量的使用
  在一个task被多个线程运行的时候,那么这个task中的属性就成了共享属性,但是有时候,我们并不想变量被所有线程共享,这个时候 就要用到 线程局部变量(Thread-Local Variable)机制了.


用ThreadLocal来包装,并初始化. 而不是使用private Date loc;
        线程的局部变量为每个线程储备了各自的属性值,可以使用get()方法读取这个值,并用set()方法设置这个值。若线程第一次访问线程局部变量时,该变量还没有值,就调用initialValue()来赋值。
1.11.线程的分组
  ThreadGroup(线程组): 表示一组线程,可以包含线程对象,也可以包含线程组对象,它是一个树形结构. 
  在某些情况下,线程分组比较好控制,比如在多个线程运行中,你要控制他们.只需要一个单一的操作就能达到效果.



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值