目录:
- 线程的基本状态
- 基础操作
基本状态
进程和线程的关联: 在《高并发程序设计》中,作者的比喻十分巧妙。
进程是一个容器,比如一间明亮的小别墅,里面的电视、厨房、洗手间等都是临界资源,一家三口各为独立线程,当他们各司其职,互不干扰,比如,妈妈在厨房做饭,爸爸在书房工作,女儿在客厅看卡通节目,一家其乐融融,小别墅的生活就十分惬意。但当爸爸想去客厅看体育频道时,就和女儿产生了资源的竞争,这就是我们需要解决的冲突。
这里有个面试常出现的点:为什么并发程序设计使用多线程而不是多进程?
-
线程是程序最小执行单位;
-
线程间的切换和调度成本远小于进程;
线程的状态在Thread的State枚举中:
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}.
*/
// 执行过程,遇到synchronized同步块阻塞,暂停执行,直到获得锁
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.
*/
// 调用wait() -> notify()唤醒,join() -> 等待目标线程终止,LockSupport.park(),进入无时间限制的等待
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>
*/
// 进入有时限的等待, 调用sleep(Long),wait(Long),join(Long)
TIMED_WAITING,
/**
* Thread state for a terminated thread.
* The thread has completed execution.
*/
TERMINATED;
}
基本操作
-
新建线程
-
继承Thread,重写run(), 或使用匿名内部类重写run()方法
//jdk8之前 Thread t1 = new Thread(){ @Override public void run() { System.out.println("hello"); } }; t1.start(); // jdk8之后 new Thread(() -> System.out.println("hello")).start();
-
实现Runnable接口,实现run():
public class CreateThread implements Runnable { @Override public void run() { System.out.println("hello"); } public static void main(String[] args) { CreateThread createThread = new CreateThread(); Thread t1 = new Thread(createThread); // createThread.start(); 无此方法,start()由Thread类独有 t1.start(); } }
-
实现Callable(),实现call(),有返回值,可抛出异常:
public class CreateThread implements Callable { @Override public Object call() throws Exception { return "hello"; } public static void main(String[] args) { CreateThread createThread = new CreateThread(); FutureTask futureTask = new FutureTask(createThread); Thread thread = new Thread(futureTask).s; thread.start(); System.out.println(futureTask.get()); } }
-
-
启动线程
Warning:使用Thread的start()方法启动线程,而不是run()。若执行run(), 相当于在当前线程,执行常规的方法调用。
使用实现Runnable接口创建线程,更为合理,理由如下:
- 在java中,继承是很宝贵的资源,为单继承;
- 以下为Thread.run()源码,target为Runnable实例,因此使用实现Runnable接口创建线程,更为合理
/** * If this thread was constructed using a separate * <code>Runnable</code> run object, then that * <code>Runnable</code> object's <code>run</code> method is called; * otherwise, this method does nothing and returns. * <p> * Subclasses of <code>Thread</code> should override this method. * * @see #start() * @see #stop() * @see #Thread(ThreadGroup, Runnable, String) */ @Override public void run() { if (target != null) { target.run(); } }
-
中断线程
通过设置中断标志位状态,在业务代码中,可执行善后工作
与线程中断相关,有三个方法
-
interrupt()
-
isInterrupted()
@Override public void run() { while(true) { if (Thread.currentThread().isInterrupted()) { System.out.println("Interrupted"); break; } } }
-
Thread.interrupted() //静态方法,判断是否中断,并清除当前中断状态
warning: wait()及sleep()操作,当等待/阻塞时,如果被中断,会抛出InterruptedException,并清除中断标记。
-
-
终止线程
使用中断代替强制终止
java中存在一个被废弃的stop(),理由是他太过于暴力,可能引起数据不一致的问题。