Java多线程系列1 线程创建以及状态切换
我们知道线程线程有三种创建方式
1实现Runnable接口
2 继承Thread类
3使用Callable和Future接口创建线程。具体是创建Callable接口的实现类,并实现clall()方法。并使用FutureTask类来包装Callable实现类的对象,且以此FutureTask对象作为Thread对象的target来创建线程。
好处:假设有一个很耗时的返回值需要计算,并且这个返回值不是立刻需要的话,那么就可以使用这个组合,用另一个线程去计算返回值,而当前线程在使用这个返回值之前可以做其它的操作,等到需要这个返回值时,再通过Future得到,后面会说道future模式
代码如下
public class test { public static void main(String[] args) { MyThread callable = new MyThread(); FutureTask<Integer> task = new FutureTask<>(callable); new Thread(task).start(); try { Thread.sleep(1000);// 一些其他操作 System.out.println(task.get()); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ExecutionException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } class MyThread implements Callable<Integer> { @Override public Integer call() throws Exception { return new Random().nextInt(); } }
接下来说说线程的状态切换
图片来自网络,侵删。
新建状态(New):当线程对象对创建后,即进入了新建状态
就绪状态(Runnable):当调用线程对象的start()方法(t.start();),线程即进入就绪状态。处于就绪状态的线程,只是说明此线程已经做好了准备,能否在执行需要看待cpu的调度。
运行状态(Running):当cpu调度到该线程,该线程就会运行。
阻塞状态(Blocked):线程因为某些原因,暂时被挂起,暂时不继续执行的状态。常见的有以下三种
1.等待阻塞:运行状态中的线程执行wait()方法,使本线程进入到等待阻塞状态;
2.同步阻塞 -- 线程在获取synchronized同步锁失败(因为锁被其它线程所占用),它会进入同步阻塞状态;
3.其他阻塞 -- 通过调用线程的sleep()或join()或发出了I/O请求时,线程会进入到阻塞状态。当sleep()状态超时、join()等待线程终止或者超时、或者I/O处理完毕时,线程重新转入就绪状态。
死亡状态(Dead):线程执行完了或者因异常退出了run()方法,该线程结束生命周期。
请注意:::::
只有使用yield()方法以后 线程从运行到就绪状态
无论使用 wait(),synchronized 关键词还是sleep() join() 都是先进入阻塞 当满足了相关条件以后,在进入就绪状态
最后要说明的是,关于线程的死亡 可以看到已经废弃了stop方法,因为使用了该方法会释放所有锁,引发数据安全问题
实际开发中,我们要结束一个线程,一般通过设置一个Boolean标志位来 如下面代码所示
public class test { public static void main(String[] args) { MyThread t = new MyThread(); t.start(); try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } t.setExit(); } } class MyThread extends Thread { private volatile boolean exit = true; @Override public void run() { while (exit) { System.out.println("hello"); } } public void setExit() { this.exit = false; } }
posted on 2017-05-07 21:51 一只小蜗牛12138 阅读(186) 评论(0) 编辑 收藏 举报