java并发编程之Thread类详细使用(四)

来源:互联网 发布:mac sierra重装系统 编辑:程序博客网 时间:2024/06/05 15:25

原博文地址:http://www.cnblogs.com/dolphin0520/p/3920357.html

1.线程的状态:new(创建)->runnable(就绪)->running(运行),运行时又分状态:阻塞(blocked),time waiting(睡眠或等待一定的事件),waiting(等待被唤醒)。

线程执行完毕,或者突然中断,进入dead(死亡or销毁)状态。如下图所示:

2.Thread之sleep()方法:

1)sleep相当于让线程睡眠,交出CPU,让CPU去执行其他的任务。

2)sleep方法不会释放锁,也就是说如果当前线程持有对某个对象的锁,则即使调用sleep方法,其他线程也无法访问这个对象。

例子如下:

public class Threadsleep {    private int i = 10;    private Object object = new Object();         public static void main(String[] args) throws IOException  {    Threadsleep threadsleep = new Threadsleep();    //下面两个线程共享threadsleep对象        MyThread thread1 = threadsleep.new MyThread();        MyThread thread2 = threadsleep.new MyThread();        thread1.start();        thread2.start();    }          class MyThread extends Thread{        @Override        public void run() {            synchronized (object) {                i++;                System.out.println("i:"+i);                try {                    System.out.println("线程"+Thread.currentThread().getName()+"进入睡眠状态");                    Thread.currentThread().sleep(10000);                } catch (InterruptedException e) {                    // TODO: handle exception                }                System.out.println("线程"+Thread.currentThread().getName()+"睡眠结束");                i++;                System.out.println("i:"+i);            }        }    }}

结果:


结论:当Thread-0进入睡眠状态之后,Thread-1并没有去执行具体的任务。只有当Thread-0执行完之后,此时Thread-0释放了对象锁,Thread-1才开始执行。

3.Thread之join()方法:

join()join(long millis)     //参数为毫秒join(long millis,int nanoseconds)    //第一参数为毫秒,第二个参数为纳秒

1)假如在main线程中,调用thread.join方法,则main方法会等待thread线程执行完毕或者等待一定的时间。

2)如果调用的是无参join方法,则等待thread执行完毕,如果调用的是指定了时间参数的join方法,则等待一定的事件。

例子如下:

public class Threadjoin {        public static void main(String[] args) throws IOException  {        System.out.println("进入线程"+Thread.currentThread().getName());        Threadjoin threadjoin = new Threadjoin();        MyThread thread1 = threadjoin.new MyThread();        thread1.start();        try {            System.out.println("线程"+Thread.currentThread().getName()+"等待");            thread1.join();            System.out.println("线程"+Thread.currentThread().getName()+"继续执行");        } catch (InterruptedException e) {            // TODO Auto-generated catch block            e.printStackTrace();        }    }          class MyThread extends Thread{        @Override        public void run() {            System.out.println("进入线程"+Thread.currentThread().getName());            try {                Thread.currentThread().sleep(5000);            } catch (InterruptedException e) {                // TODO: handle exception            }            System.out.println("线程"+Thread.currentThread().getName()+"执行完毕");        }    }}
结果:

结论:1)当调用thread1.join()方法后,main线程会进入等待。然后等待thread1执行完之后再继续执行。

2)thread1.join()后让main线程进入阻塞状态,并且会释放线程占有的锁,并交出CPU执行权限。

4.Thread之interrupt方法:

1)interrupt,顾名思义,即中断的意思。

2)单独调用interrupt方法可以使得处于阻塞状态的线程抛出一个异常,也就说,它可以用来中断一个正处于阻塞状态的线程。

例子如下:

public class Threadinterrupt {   public static void main(String[] args) throws IOException  {Threadinterrupt threadinterrupt = new Threadinterrupt();        MyThread thread = threadinterrupt.new MyThread();        thread.start();        try {            Thread.currentThread().sleep(2000);        } catch (InterruptedException e) {                     }        thread.interrupt();    }          class MyThread extends Thread{        @Override        public void run() {            try {                System.out.println("进入睡眠状态");                Thread.currentThread().sleep(10000);                System.out.println("睡眠完毕");            } catch (InterruptedException e) {                System.out.println("得到中断异常");            }            System.out.println("run方法执行完毕");        }    }}
结果:

结论:1)interrupt方法可以中断处于阻塞状态的线程。

问题:interrupt能不能中断处于非阻塞状态的线程呢?如下例子:

public class Threadinterrupt2 {   public static void main(String[] args) throws IOException  {Threadinterrupt2 threadinterrupt2 = new Threadinterrupt2();        MyThread thread = threadinterrupt2.new MyThread();        thread.start();        try {            Thread.currentThread().sleep(2000);        } catch (InterruptedException e) {                     }        thread.interrupt();    }          class MyThread extends Thread{        @Override        public void run() {            int i = 0;            while(i<Integer.MAX_VALUE){                System.out.println(i+" while循环");                i++;            }        }    }}

结论:通过测试结果,发现直接调用interrupt方法不能中断正在运行中的线程

问题:如何中断正在运行的线程呢?

1)一般会在MyThread类中增加一个属性 isStop来标志是否结束while循环,然后再在while循环中判断isStop的值。如下:

class MyThread extends Thread{        private volatile boolean isStop = false;        @Override        public void run() {            int i = 0;            while(!isStop){                i++;            }        }                 public void setStop(boolean stop){            this.isStop = stop;        }    }

那么就可以在外面通过调用setStop方法来终止while循环。

5.Thread其他方法:

1)getId 用来得到线程ID。

2)getName和setName。用来得到或者设置线程名称。

3)getPriority和setPriority。用来获取和设置线程优先级。

4)setDaemon和isDaemon。用来设置线程是否成为守护线程和判断线程是否是守护线程。

5)currentThread()。常用,用来获取当前线程。

演示关系图如下:


原创粉丝点击