J.U.C:线程基本概念
Posted 恒奇恒毅
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了J.U.C:线程基本概念相关的知识,希望对你有一定的参考价值。
进程与线程
进程(Process) 是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。 在当代面向线程设计的计算机结构中,进程是线程的容器。程序是指令、数据及其组织形式的描述,进程是程序的实体。是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配和调度的基本单位,是操作系统结构的基础。程序是指令、数据及其组织形式的描述,进程是程序的实体。
线程(thread) 是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
线程的状态
/**
* A thread state. A thread can be in one of the following states:
* <ul>
* <li>@link #NEW<br>
* A thread that has not yet started is in this state.
* </li>
* <li>@link #RUNNABLE<br>
* A thread executing in the Java virtual machine is in this state.
* </li>
* <li>@link #BLOCKED<br>
* A thread that is blocked waiting for a monitor lock
* is in this state.
* </li>
* <li>@link #WAITING<br>
* A thread that is waiting indefinitely for another thread to
* perform a particular action is in this state.
* </li>
* <li>@link #TIMED_WAITING<br>
* A thread that is waiting for another thread to perform an action
* for up to a specified waiting time is in this state.
* </li>
* <li>@link #TERMINATED<br>
* A thread that has exited is in this state.
* </li>
* </ul>
*
* <p>
* A thread can be in only one state at a given point in time.
* These states are virtual machine states which do not reflect
* any operating system thread states.
*
* @since 1.5
* @see #getState
*/
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;
线程有NEW(新建)、RUNNABLE(就绪)、BLOCKED(阻塞)、WAITING(不见不散)、TIMED_WAITING(过时不候)、TERMINATED(终止)这六种状态。
NEW
表示线程处于新建状态,还不可以运行
RUNNABLE
表示线程处于就绪状态,可以被调度器调度运行,调用线程的start方法后进入该状态。
BLOCKED
表示线程在等待同步监视器锁,一般是在竞争syncronized的锁或者进入syncronized之后调用了Object.wait方法
WAITING
表示线程处于等待状态,一般是调用了以下三个方法之一:
Object#wait()不带参的
相应地需要对应监视器对象调用notify或者notifyAll方法或者被中断interrupted
Thread.join()不带参的
相应地需要另外的线程执行完成
LockSupport#park()方法
相应地需要调用LockSupport#unpark()方法
TIMED_WAITING
表示线程处于带时等待状态,一般是调用了以下五个方法之一:
Thread.sleep(long)
需要等待线程休眠时间到或者被中断interrupted
Object#wait(long)
相应地需要对应监视器对象调用notify或者notifyAll方法或者被中断interrupted
Thread.join(long)
相应地需要另外的线程执行完成
LockSupport#parkNanos
相应地需要调用LockSupport#unpark()方法
LockSupport#parkUntil
相应地需要调用LockSupport#unpark()方法
TERMINATED
线程的终止状态
wait和sleep
- sleep 是 Thread 的静态方法,wait 是 Object 的方法,任何对象实例都能调用。
- sleep 不会释放锁,它也不需要占用锁。wait 会释放锁,但调用它的前提是当前线程占有锁(即代码要在 synchronized 中)。
- 它们都可以被 interrupted 方法中断。
并行与并发
并行是表示同时做多件事情,对于单核CPU来说,是达不到并行的效果的。并行标示的是同时做do多件事的能力。
并发是看起来是同时在做多件事情,对于单核CPU来说,同一时刻只可能一个线程在运行。并发表示的是同时处理handle多件事情的能力。
所以,只有多核CPU才能真正利用好多线程能力。
用户线程和后台线程
用户线程:也叫前台线程,平时用到的普通线程,自定义线程setDaemon(false),默认就是前台线程
守护线程:运行在后台,是一种特殊的线程,setDaemon(true),比如垃圾回收
- 当主线程结束后,用户线程还在运行,JVM 存活
- 如果没有用户线程,都是守护线程,JVM 结束
这里的一个很好的利用就是:如何优雅地保证程序不退出?
创建线程的三种方式
继承Thread类,重写run方法
@Override
public void run()
if (target != null)
target.run();
实现Runnable接口,传入Thread构造方法
因为默认的Thread#run
方法是运行Runnable
的,所以如果我们既通过Thread
的构造方法传入Runnable
,又复写了Thread#run
方法,那么会以Thread#run
方法为准,构造方法传入的Runnable
就不起作用了。
实现Callable接口配合FutureTask
如果要实现能获取到返回值,可以实现Callable
接口(一般是比较耗时的),并配合FutureTask
。FutureTask
既实现了Runnable
,又实现了Future
接口。通过Future
的get
方法就可以获取到结果。
public interface Future<V>
/**
* Attempts to cancel execution of this task. This attempt will
* fail if the task has already completed, has already been cancelled,
* or could not be cancelled for some other reason. If successful,
* and this task has not started when @code cancel is called,
* this task should never run. If the task has already started,
* then the @code mayInterruptIfRunning parameter determines
* whether the thread executing this task should be interrupted in
* an attempt to stop the task.
*
* <p>After this method returns, subsequent calls to @link #isDone will
* always return @code true. Subsequent calls to @link #isCancelled
* will always return @code true if this method returned @code true.
*
* @param mayInterruptIfRunning @code true if the thread executing this
* task should be interrupted; otherwise, in-progress tasks are allowed
* to complete
* @return @code false if the task could not be cancelled,
* typically because it has already completed normally;
* @code true otherwise
*/
boolean cancel(boolean mayInterruptIfRunning);
/**
* Returns @code true if this task was cancelled before it completed
* normally.
*
* @return @code true if this task was cancelled before it completed
*/
boolean isCancelled();
/**
* Returns @code true if this task completed.
*
* Completion may be due to normal termination, an exception, or
* cancellation -- in all of these cases, this method will return
* @code true.
*
* @return @code true if this task completed
*/
boolean isDone();
/**
* Waits if necessary for the computation to complete, and then
* retrieves its result.
*
* @return the computed result
* @throws CancellationException if the computation was cancelled
* @throws ExecutionException if the computation threw an
* exception
* @throws InterruptedException if the current thread was interrupted
* while waiting
*/
V get() throws InterruptedException, ExecutionException;
/**
* Waits if necessary for at most the given time for the computation
* to complete, and then retrieves its result, if available.
*
* @param timeout the maximum time to wait
* @param unit the time unit of the timeout argument
* @return the computed result
* @throws CancellationException if the computation was cancelled
* @throws ExecutionException if the computation threw an
* exception
* @throws InterruptedException if the current thread was interrupted
* while waiting
* @throws TimeoutException if the wait timed out
*/
V get(long timeout, TimeUnit unit)
throws InterruptedException, ExecutionException, TimeoutException;
public interface RunnableFuture<V> extends Runnable, Future<V>
/**
* Sets this Future to the result of its computation
* unless it has been cancelled.
*/
void run();
public FutureTask(Callable<V> callable)
if (callable == null)
throw new NullPointerException();
this.callable = callable;
this.state = NEW; // ensure visibility of callable
以上是关于J.U.C:线程基本概念的主要内容,如果未能解决你的问题,请参考以下文章