系列:多线程(一)Thread
属性
属性 | 说明 | 作用 |
---|---|---|
name | 线程名称 | |
priority | 线程优先级 | |
daemon | 线程是否守护线程,true是false否 |
private static int threadInitNumber;
用于匿名线程的自动编号,作用于name属性
For generating thread ID
用于产生线程Id,作用于id属性
private Runnable target;
将要run的Runnable
private ThreadGroup group;
当前线程所属线程组
private volatile int threadStatus = 0;
线程状态
Thread.State
- NEW 未开始
- RUNNABLE 正执行或就绪
- BLOCKED 阻塞于monitor Lock
- WAITING 等待另一个线程notify
调用Object.wait(), Thread.join(), LockSupport.park进入waiting - TIMED_WAITING 在指定时间内等待另一个线程notify
调用Thread.sleep, Object.wait(long), Thread.join(long), LockSupport.parkNanos, LockSupport.parkUntil进入timed_waiting - TERMINATED exited
方法
public static native Thread currentThread();
public static native void yield();
public static native void sleep(long millis) throws InterruptedException;
The thread does not lose ownership of any monitors.
public final native boolean isAlive();
public final void join() throws InterruptedException
实现:wait。不过不需要notify通知
中断/中断异常
中断:public void interrupt()
线程阻塞在:
Object#wait() Object#wait(long) Object#wait(long, int)
#join() #join(long) #join(long, int)
#sleep(long) #sleep(long, int)
调用interrupt(),会抛异常,捕获该异常,将会clear中断状态位
线程阻塞在:java.nio.channels.InterruptibleChannel InterruptibleChannel
channel将会被关闭
中断状态位被set
接收java.nio.channels.ClosedByInterruptException
线程阻塞在:java.nio.channels.Selector
中断状态位被set
立即从selection操作返回
如果没有以上条件,中断位将被set
中断位getter:
// 参数为:boolean ClearInterrupted,true会重置标识位
public static boolean interrupted() {
return currentThread().isInterrupted(true);
}
public boolean isInterrupted() {
return isInterrupted(false);
}
中断异常:InterruptedException。抛出异常后中断状态会被clear
The interrupted status of the current thread is cleared when this exception is thrown
异常处理器
在run方法中是不能够抛出异常的
- 已检查的异常,那么必须进行try catch
- 对于未检查的异常,如果没有进行处理,一旦抛出线程将会宕掉,而且在主线程中并不能捕获到这个异常
在Java线程的run方法中,对于未检查异常,借助于异常处理器进行处理的
废弃方法
Thread.stop
这个方法会解除被加锁的对象的锁,因而可能造成这些对象处于不一致的状态,而且这个方法造成的ThreadDeath异常不像其他的检查期异常一样被捕获。
(太过于暴力,强行把执行到一半的线程终止,并且会立即释放这个线程所有的锁。会破坏了线程中引用对象的一致性。)
可以使用interrupt方法代替。事实上,如果一个方法不能被interrupt,那stop方法也不会起作用。
Thread.suspend, Thread.resume
这俩方法有造成死锁的危险。使用suspend时,并不会释放锁;而如果我想先获取该锁,再进行resume,就会造成死锁。
可以使用object的wait和notify方法代替。wait方法会释放持有的锁。
实现线程常见方式
- 继承Thread
- 实现Runnable
- 实现Callable
- Callable + Future
- Callable + FutureTask
- 线程池
// 继承Thread
Thread thread = new Thread(() -> System.out.println("a"));
thread.start();
// 实现Runnable
Runnable runnable = () -> System.out.println("b");
new Thread(runnable).start();
// Callable + Future: 线程池.submit
// Callable + FutureTask: 线程池.submit或Thread.start
Callable<String> callable = () -> {
TimeUnit.SECONDS.sleep(1);
return "a";
};
ThreadPoolExecutor poolExecutor = new ThreadPoolExecutor(1, 1, 0, TimeUnit.SECONDS, new ArrayBlockingQueue<>(10));
Future<String> future = poolExecutor.submit(callable);
System.out.println(future.get());
FutureTask task = new FutureTask(callable);
new Thread(task).start();
System.out.println(task.get());
poolExecutor.submit(task);
poolExecutor.shutdown();
System.out.println(task.get());
参考
Thread注释 JDK 8
https://www.cnblogs.com/noteless/category/1394612.html
https://www.cnblogs.com/bethunebtj/p/5806749.html
https://www.jianshu.com/p/0cf9cadd25a7
https://blog.csdn.net/a158123/article/details/78776145