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();
} }

  

接下来说说线程的状态切换

图片来自网络,侵删。

Java多线程系列1 线程创建以及状态切换

新建状态(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;
}
}

  

上一篇:BZOJ3688: 折线统计


下一篇:用int还是用Integer?