Java线程
图解:https://images0.cnblogs.com/i/426802/201406/232002051747387.jpg
Java 线程的5中基本状态
1.新建状态
当new一个线程对象完成后,这个线程对象就处于新建状态了。
Thread t = new Thread();//此时t处于新建状态。
2.就绪状态
当线程对象调用了start()方法后,线程就处于就绪状态了,等待CPU的调度执行(获取时间片)。
当start()方法调用后,并不是说能够立即执行线程对象的run()方法。
t.start();//线程准备好执行了,等待CPU调度。
3.运行状态
当CPU开始调度处于就绪状态的线程时(线程获取CPU的执行权限),此时线程才开始真正的执行,此时执行的是线程对象的run()方法。
只有就绪状态可以进入运行状态!!!
public void run(){ System.out.println("hello"); //当执行run内部的语句时,线程处于运行状态。 }
4.阻塞状态
处于运行状态的线程,由于某些原因,暂时放弃CPU的使用权,停止执行,此时就处于阻塞状态,直到线程进入就绪状态,才有可能再次获取CPU的执行权限,进入到运行状态。(个人猜测线程池的原理就是维持多个线程,当线程任务完成后,通过一些其他操作使的线程处于阻塞状态,当再次把任务交给线程池执行的时候,线程池将处于阻塞状态的线程通过操作处于就绪状态,然后开始执行线程任务,如此循环,避免的多次的创建线程。)。
4.1等待阻塞
运行状态的线程内部执行了wait()方法,使该线程处于等待阻塞状态,wait()方法是Object类提供的。
4.2同步阻塞
线程在获取synchronize同步锁失败,然后等待其他线程释放同步锁,获取执行权限,此时处于同步阻塞。
4.3其他阻塞
通过调用线程的sleep()或者join()或者发出I/O请求时,线程也会进入到阻塞状态。当sleep()状态超时或者join()等待线程终止或超时、或者I/O操作处理完成时,线程重新进入就绪状态。
5.死亡状态
线程执行完成run()方法,或者执行中抛出异常,终止执行,线程声明周期结束。
Java多线程的实现方式
1.继承Thread类,并重写run()方法。
2.实现Runnable接口,并将Runnable接口的对象作为Thread的target。
3.实现Callable和Future接口创建线程。使用FutureTask类来包装Callable实现类,之后用线程包裹
这种实现的线程执行是有返回值的,使用FutureTask的get方法取得返回值,在调用了这个方法后,会阻塞线程(调用线程),直到取到返回值为止。
注:同一个线程对象,只能调用一次start()方法。
Java中线程状态的转换
1. 就绪->运行:线程获得CPU的执行权限
2. 运行->就绪:线程失去CPU的执行权限,或者主动放弃CPU的执行权限,调用yield()方法
3. 运行->死亡:线程正常执行完成或者执行中抛出异常
线程池
```
//创建线程池
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
//实际的创建方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
//ThreadPoolExecutor 的构造方法重载
public ThreadPoolExecutor(int corePoolSize,//核心线程数
int maximumPoolSize,//最大线程数
long keepAliveTime,//当前线程池中实际的线程数大于核心线程数小于最大线程数时,空闲线程的存活时间
TimeUnit unit,//存活时间的单位
BlockingQueue<Runnable> workQueue,//阻塞队列,保存向线程池中提交的任务
ThreadFactory threadFactory,//创建线程的工厂
RejectedExecutionHandler handler) {//当队列已满时处理新添加任务的处理器,可以自定义
if (corePoolSize < 0 ||
maximumPoolSize <= 0 ||
maximumPoolSize < corePoolSize ||
keepAliveTime < 0)
throw new IllegalArgumentException();
if (workQueue == null || threadFactory == null || handler == null)
throw new NullPointerException();
this.acc = System.getSecurityManager() == null ?
null :
AccessController.getContext();
this.corePoolSize = corePoolSize;
this.maximumPoolSize = maximumPoolSize;
this.workQueue = workQueue;
this.keepAliveTime = unit.toNanos(keepAliveTime);
this.threadFactory = threadFactory;
this.handler = handler;
}
//执行任务
ExecutorService.submit();
public Future<?> submit(Runnable task) {
if (task == null) throw new NullPointerException();
RunnableFuture<Void> ftask = newTaskFor(task, null);
execute(ftask);
return ftask;
}
/**
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public <T> Future<T> submit(Runnable task, T result) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task, result);
execute(ftask);
return ftask;
}
/**
* @throws RejectedExecutionException {@inheritDoc}
* @throws NullPointerException {@inheritDoc}
*/
public <T> Future<T> submit(Callable<T> task) {
if (task == null) throw new NullPointerException();
RunnableFuture<T> ftask = newTaskFor(task);
execute(ftask);
return ftask;
}
//不管是执行submit提交的Runnable对象还是Callable对象。最终都是调用过了execute(Runnable runnable)方法。
ExecutorService.execute(Runnable runnable);
具体实现是由ThreadPoolExecutor实现的
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
/*
* Proceed in 3 steps:
*
* 1. If fewer than corePoolSize threads are running, try to
* start a new thread with the given command as its first
* task. The call to addWorker atomically checks runState and
* workerCount, and so prevents false alarms that would add
* threads when it shouldn't, by returning false.
*
* 2. If a task can be successfully queued, then we still need
* to double-check whether we should have added a thread
* (because existing ones died since last checking) or that
* the pool shut down since entry into this method. So we
* recheck state and if necessary roll back the enqueuing if
* stopped, or start a new thread if there are none.
*
* 3. If we cannot queue task, then we try to add a new
* thread. If it fails, we know we are shut down or saturated
* and so reject the task.
*/
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))//添加到任务队列中
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);//拒绝执行
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
其中的addWorker()方法
private boolean addWorker(Runnable firstTask, boolean core) {
retry:
for (;;) {//内部的双层无限循环不停的检测线程池中线程的状态
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN &&
! (rs == SHUTDOWN &&
firstTask == null &&
! workQueue.isEmpty()))
return false;
for (;;) {
int wc = workerCountOf(c);
if (wc >= CAPACITY ||
wc >= (core ? corePoolSize : maximumPoolSize))
return false;
if (compareAndIncrementWorkerCount(c))
break retry;
c = ctl.get(); // Re-read ctl
if (runStateOf(c) != rs)
continue retry;
// else CAS failed due to workerCount change; retry inner loop
}
}
boolean workerStarted = false;
boolean workerAdded = false;
Worker w = null;//worker类是一个内部类,实现了Runnable接口,内部有一个线程,使用线程工厂对象创建
try {
w = new Worker(firstTask);
final Thread t = w.thread;
if (t != null) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// Recheck while holding lock.
// Back out on ThreadFactory failure or if
// shut down before lock acquired.
int rs = runStateOf(ctl.get());
if (rs < SHUTDOWN ||
(rs == SHUTDOWN && firstTask == null)) {
if (t.isAlive()) // precheck that t is startable
throw new IllegalThreadStateException();
workers.add(w);
int s = workers.size();
if (s > largestPoolSize)
largestPoolSize = s;
workerAdded = true;
}
} finally {
mainLock.unlock();
}
if (workerAdded) {
t.start();
workerStarted = true;
}
}
} finally {
if (! workerStarted)
addWorkerFailed(w);
}
return workerStarted;
}
```