Chinaunix首页 | 论坛 | 博客
  • 博客访问: 66084
  • 博文数量: 43
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 420
  • 用 户 组: 普通用户
  • 注册时间: 2014-06-27 15:04
个人简介

记录,分享

文章分类

全部博文(43)

文章存档

2017年(24)

2015年(1)

2014年(18)

我的朋友

分类: Java

2017-03-16 12:08:39

一、创建线程并启动
 1.两种方式
  • 创建一个Thread子类的实例,并调用其start方法
  • 创建一个实现Runnable接口的类的实例,并以此实例作为target参数构造一个Thread实例,
 2.两种方式的比较
  • 将同一个Runnable实例的引用作为多个Thread实例的target构造参数,可以实现资源的共享。因此,Runnable适合于多个相同程序代码线程去处理统一资源的情况,把虚拟的cpu(线程)同程序的代码,数据有效分离,较好体现面向对象的编程的思想
  • Runnable可以避免由于java的单继承机制带来的局限。可以再继承其他类的同时,还能实现多线程的功能。

二、中断线程

 1.中断的方式:调用interrupt方法
 2.关于interrupt方法
  • 当interrupt方法被调用后,线程的执行并未真的中断,而是将中断状态置位,这是每个java线程都具有的boolean标志。每个线程都应该不停地检查这个状态,以判断线程是否被中断。
while(!Thread.CurrentThread().isInterrupted()){...}
  • 如果在每次工作迭代后都调用sleep方法,则isInterrupted检测既无必要也无用处,而应直接捕捉 InterruptedException 。因为在一个 isInterrupted为true的线程上调用sleep方法,它不会休眠。相反,它将清除这一状态并抛出 InterruptedException
  • 当一个线程被阻塞(sleep,wait),此线程的 interrupt被调用时,阻塞调用会被InterruptedException中断
  • 对 InterruptedException的处理,一种做法是在catch块中调用Thread.CurrentThread().interrupt();以使调用者可以检测。
  • InterruptedException异常被处理后,程序设计者可以决定线程继续执行还是正常结束。

三、控制线程的结束

    如果获得了一个线程的引用,可以调用join等待该线程结束。
    对于一个持续工作的线程, run方法内可写成while(needEnd){...}的形式 ,通过更改boolean成员变量 needEnd 来控制线程的结束。

四、线程状态
1. NEW  -  A thread that has not yet started is in this state. 

2. RUNNABLE  -  A thread executing in the Java virtual machine is in this state. 

3. BLOCKED  -  A thread that is blocked waiting for a monitor lock is in this state. Include:
    synchronized(lock) { .. }

4. WAITING  -  A thread that is waiting indefinitely for another thread to perform a particular action is in this state. Include:
    (1) Object.wait with no timeout
    (2) Thread.join with no timeout
    (3) LockSupport.park
 
5. TIMED_WAITING  -  A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. Include:
    (1) Thread.sleep
    (2) Object.wait with timeout
    (3) Thread.join with timeout
    (4) LockSupport.parkNanos
    (5) LockSupport.parkUntil

6. TERMINATED  -  A thread that has exited is in this state.

假设t1,t2先后两个线程,都执行如下代码:
synchronized(Obj){Obj.wait();}
t1先进,最后在Obj.wait()下卡住,这时java管t1的状态为waitting状态,是线程主动等待其他线程唤醒自己。
t2后进,直接在第一行就卡住了,这时java叫t2为blocked状态,是线程进临界区时被动(被jvm)阻塞住。


五、守护线程
    jvm内线程分为用户线程和守护线程,两种线程没有实质区别,但是jvm会等待所有用户线程执行完才会退出,而不会等待守护线程。守护线程常用来做监控,但是不适合做IO,因为jvm随时可能退出。
    守护线程需要在调用start前设置,否则会抛出IllegalStateExeption。
    守护线程产生的线程仍是守护线程。
    守护线程与unix守护进程的概念没有任何关系。

六、未捕获异常处理器
    Thread的run方法不能抛出任何可被检测的异常,但是不被检测的异常被抛出会导致线程终止。为避免这一情况,可以为线程设置未捕获异常处理器,被抛出的未检测异常会被传递到该处理器来处理。

static void setDefaultUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh) 
void setUncaughtExceptionHandler(Thread.UncaughtExceptionHandler eh)

    未检测异常被抛出时,先获取默认处理器,如果未安装,则获取该线程独立处理器,如果也未安装,则此线程的异常处理器为该Thread所属ThreadGroup,因为ThreadGroup实现了Thread.UncaughtExceptionHandler接口。

七、线程组(ThreadGroup)

可以把线程归属到某一个线程组中,线程组中可以有线程对象,也可以有线程组,组中还可以有线程,这样的组织结构有点类似于树的形式,如图所示:

线程组的作用是:可以批量管理线程或线程组对象,有效地对线程或线程组对象进行组织,例如将一组线程放到同一个ThreadGroup中,通过ThreadGroup实例进行start/interrupt。

public class ThreadGroupSample {
    public static void main(String[] args) {
        TestThread mt0 = new TestThread();
        TestThread mt1 = new TestThread();
        ThreadGroup tg = new ThreadGroup("新建线程组1");
        Thread t0 = new Thread(tg, mt0);
        Thread t1 = new Thread(tg, mt1);
        t0.start();
        t1.start();
        System.out.println("活动的线程数为:" + tg.activeCount());
        System.out.println("线程组的名称为:" + tg.getName());
        try {
            Thread.sleep(6000);
        } catch (InterruptedException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        tg.interrupt();
    }
}
class TestThread implements Runnable{
    @Override
    public void run() {
        try
        {
            while (!Thread.currentThread().isInterrupted())
            {
                System.out.println("ThreadName = " + Thread.currentThread().getName());
                Thread.sleep(1000);
            }
        }
        catch (InterruptedException e)
        { }
        System.out.println(Thread.currentThread().getName() + " is interrupted");
    }
}




阅读(330) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~