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

原博文地址: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()。常用,用来获取当前线程。

演示关系图如下:


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值