实现线程
1.继承Thread 2.实现Runnable
区别:一个类只能启动一个线程 可以启动多个对象线程
class Mythread extends Thread{ class Mythread2 implements Runnable{
public void run(){ ....} public void run(){ ....}
public static void main(String[] args){ public static void main(String[] args){
Mythread mythread =new Mythread(); Mythread2 mythread2=new Mythread2();
mythread.start(); Thread thread=new Thread(mythread2);
thread.start();
} }
} }
终止线程 :三种方法:
1.使用退出标识,使线程正常退出,即当run()方法完成后线程终止
2.使用stop 方法,但这个方法会发生不可意料的结果,已过时
3.使用interrupt方法可以用来请求中断线程
interrupt() : 向线程发出中断请求,将线程的中断状态设为true,如果该线程被一个sleep调用阻塞,则抛出异常
interrupted() : 静态方法,检测当前的线程是否被中断,若中断,则清除该线程的中断状态
isInterrupted(): 实例方法,检验是否有线程被中断。
a.线程如果被阻塞,则无法检测中断状态。若调用interrupt方法,阻塞会被Interrupted Exception中断
b.在中断状态被置位时调用sleep方法,他不会休眠,而是清除这一状态并抛出Interrupted Exception
stop和suspend的弃用:试图控制一个给定线程的行为
stop:终止所有未结束的方法,包括run方法。当线程被终止,立即释放被它锁住的所有对象的锁。这会导致对象处于不一致的状态
suspend:将线程挂起,不会破坏对象,容易造成死锁
线程的属性:线程优先级 , 守护线程, 线程组, 处理未捕获异常的处理器
setPriority,setDaemon(true), ThreadGroup类 ,setDefaultUncaughtExceptionHandler
同步:
锁对象 java.util.concurrent.locks.ReentrantLock lock()和 unlock()
条件对象 java.util.concurrent.locks.Condition await()和signalAll()
内部对象锁 synchronized
内部对象条件锁 wait notifyAll
同步阻塞 synchronized(obj) { }
监视器 只包含私有域的类,每个类的对象有一个相关的锁,该锁对所有方法加锁
Volatile 声明一个实例域来进行get和set方法的同步。原子性,可见性
final变量 final Map<String ,Double> accounts=new HashMap<>();
原子性
线程局部变量 ThreadLocal
锁测试与超时 避免线程在获得一个锁时进入阻塞队列。tryLock()视图申请一个锁,成功获得锁后返回true
读/写锁 java.util.concurrent.locks.ReentrantReadWriteLock readLock(),writeLock()
阻塞队列:
ArrayBlockingQueue
DelayQueue
LinkedBlockingQueue
PriorityBlockingQueue
方法 :offer--添加一个元素并返回true
poll--移除并返回队列的头元素
peek--返回队列的头元素
线程安全的集合:
1.映射表:ConcurrentHashMap ,ConcurrentSkipListMap
有序集:ConcurrentSkipListSet
队列 :ConcurrentLinkedQueue
2.写数组的拷贝:CopyOnWriteArrayList 所有的修改线程对底层数组进行复制。
CopyOnWriteArraySet
3.Vector和Hashtable 被ArrayList和HashMap取代 ,通过使用包装器将其变成线程安全
Callable和Future
Callable 接口类似于 Runnable,两者都是为那些其实例可能被另一个线程执行的类设计的。但是 Runnable 不会返回结果,并且无法抛出经过检查的异常。
call() 计算结果,如果无法计算结果,则抛出一个异常
Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结果,
cancel() 试图取消对此任务的执行
get() 如有必要,等待计算完成,然后获取其结果。
isCancelled() 如果在任务正常完成前将其取消,则返回 true。
isDone() 如果任务已完成,则返回 true。
线程池:一个线程池中包含许多准备运行的空闲线程,将Runnable对象交给线程池,就会有一个线程调用run方法,当run方法退出时, 线程不会死亡,而是在池中准备为下一个请求提供服务。可以减少并发线程的数目
Executor(执行器):有许多静态工厂方法用来构建线程池。
newCachedThreadPool 必要时创建新线程,空闲线程会被保留60秒
newFixedThreadPool 该池包含固定数量的线程,空闲线程会一直被保留
newSingleThreadExecutor只有一个线程的池,该线程顺序执行每一个顺序提交的任务
newScheduledThreadPool 用于预定执行而构建的固定线程池,替代java.util.Timer
newSingleThreadScheduledExecutor 用于预定执行而构建的单线程池