- 线程状态
- 线程常用方法
- Thread相关类和示例
线程状态
- 新建状态(New):新建线程对象
- 就绪状态(Runnable) 调用start()方法
- 运行状态(Running) 获得cpu的执行权限
- (有人将阻塞分为三种,等待阻塞、同步阻塞和其他阻塞;个人觉得不利于理解线程的状态)
- BLOCKED/WAITING/TIMED_WAITING
- BLOCKED: 同步代码块/等待lock
- WAITING:无限等待唤醒、没有超时时间的wait和join方法/locksupport.park()
- TIMED_WAITING: 有时限的等待、包括sleep、wait(ts)、join(ts)、locksupport.parkNanos/parkUntil
- 死亡状态(Dead) 线程执行完成或者异常退出
public enum State {
/**
* Thread state for a thread which has not yet started.
*/
NEW,
/**
* Thread state for a runnable thread. A thread in the runnable
* state is executing in the Java virtual machine but it may
* be waiting for other resources from the operating system
* such as processor.
*/
RUNNABLE,
/**
* Thread state for a thread blocked waiting for a monitor lock.
* A thread in the blocked state is waiting for a monitor lock
* to enter a synchronized block/method or
* reenter a synchronized block/method after calling
* {@link Object#wait() Object.wait}.
*/
BLOCKED,
/**
* Thread state for a waiting thread.
* A thread is in the waiting state due to calling one of the
* following methods:
* <ul>
* <li>{@link Object#wait() Object.wait} with no timeout</li>
* <li>{@link #join() Thread.join} with no timeout</li>
* <li>{@link LockSupport#park() LockSupport.park}</li>
* </ul>
*
* <p>A thread in the waiting state is waiting for another thread to
* perform a particular action.
*
* For example, a thread that has called <tt>Object.wait()</tt>
* on an object is waiting for another thread to call
* <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
* that object. A thread that has called <tt>Thread.join()</tt>
* is waiting for a specified thread to terminate.
*/
WAITING,
/**
* Thread state for a waiting thread with a specified waiting time.
* A thread is in the timed waiting state due to calling one of
* the following methods with a specified positive waiting time:
* <ul>
* <li>{@link #sleep Thread.sleep}</li>
* <li>{@link Object#wait(long) Object.wait} with timeout</li>
* <li>{@link #join(long) Thread.join} with timeout</li>
* <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
* <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
* </ul>
*/
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
线程常用方法
// 睡眠,不释放控制权
TimeUnit.MINUTES.sleep(2);
//isAlive():线程处于“新建”状态时,线程调用isAlive()方法返回false。
//在线程的run()方法结束之前,即没有进入死亡状态之前,线程调用isAlive()方法返回true.
// yield():调用此方法的线程释放当前cpu的执行权、回到就绪状态.
// join():在A线程中调用B线程join()方法,表示当执行到此方法时,直到B线程执行完毕
//(过期)suspend()和resume() 暂停和重新开始,释放cpu执行权不释放锁;stop 已过期
//暂停和重开容易造成死锁,Stop无法释放资源
//wait() 和 notify() 等待和唤醒,释放cpu执行权和锁,Object方法
//wait/notify必须在同步代码块中执行,用于生成monitorenter 和 monitorexit指令
//同步块对象锁和执行wait的对象必须是同一个(否则IllegalMonitorStateException)
//监视器和对象锁(深入理解jvm)通俗地讲就是只有获取对obj的锁定之后才能用后面代码块中的代码访问obj资源,否则就无法访问obj也无法执行后面的代码,只能让线程停滞在那里等待其它线程解除对obj的锁定;
//interrupt 中断sleep、join和wait三者之一的阻塞继续执行。设置中断标志位为true;线程还是会执行完
//提前结束等待(抛出对应的中断异常InterruptedException: sleep interrupted)
//并不真正中断正在运行的线程,而只是发出中断请求,由线程在下一个合适的时刻中断自己。中断是取消线程最合理的方式。
Thread相关类和示例
Runnable、Callable、Future、FutureTask
继承Thread就不多说了,用的比较少;Runnable看上面的例子
Callable和Runnable差不多,不过实现方法时call,而且有返回值,不能交给Thread来包装运行
@Slf4j
public class RunnableDemo implements Runnable{
@Override
public void run() {
log.info("-------10秒后大军来袭-----");
synchronized (this){
try {
this.wait(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
log.info("-------keep going-----");
}
public static void main(String[] args) {
Thread thread = new Thread(new RunnableDemo());
thread.start();
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Slf4j
public class CallableDemo implements Callable{
String callName;
public CallableDemo(String callName) {
this.callName = callName;
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
//创建一个线程池
ExecutorService pool = Executors.newFixedThreadPool(2);
//创建两个有返回值的任务
Callable c1 = new CallableDemo("A");
Callable c2 = new CallableDemo("B");
//执行任务并获取Future对象
Future f1 = pool.submit(c1);
Future f2 = pool.submit(c2);
//从Future对象上获取任务的返回值,并输出到控制台
log.info(">>>"+ f1.get().toString());
log.info(">>>"+ f2.get().toString());
//关闭线程池
pool.shutdown();
}
@Override
public Object call() throws Exception {
log.info("-----执行call方法------");
return callName + ":success";
}
}
Future是线程池的结果(泛型)类,在线程池Executor通过submit返回结果是Future;
用来查询Runnable或者Callable任务的执行情况,isDone,get等
FutureTask是一个类实现了RunnableFuture<V>,而RunnableFuture实现了Runnbale又实现了Futrue<V>这两个接口,另外它还能包装Runnale和Callable(通过适配器适配);
于是FutureTask既可以通过Thread包装来运行又可以交给ExecuteService来运行。
@Slf4j
public class FutureTaskDemo {
public static void main(String[] args) {
CallableDemo callableDemo = new CallableDemo("测试futureTask");
FutureTask futureTask1 = new FutureTask(callableDemo);
futureTask1.run(); //同步
RunnableDemo runnableDemo = new RunnableDemo();
FutureTask futureTask2 = new FutureTask(runnableDemo, Future.class);
Thread thread = new Thread(futureTask2);
thread.start();//异步
log.info("-----主线程结束----");
}
}
补充一下:
从Future的实现子类FutureTask针对cancel()方法的实现中可以看出,cancel()方法取消线程的方法是调用interrupt()方法尝试中断线程。只会去设置中断位。