1.Thread.currentThread()
返回代码段正在被哪个线程调用
注意currentThread()和this的差异
2.isAlive()
Thread.isAlive()、this.isAlive()
判断当前的线程是否处于活动状态。
3.sleep()
Thread.sleep()
4.getId()
5.Thread.interrupted():测试当前线程是否已经中断,当前线程是指运行this.interrupted()方法的线程。具有清除状态的功能
6.this.isInterrupted():测试线程是否已经中断
7.中断main线程:Thread.currentThread().interrupt();
8.线程中有for循环,如果该线程被停止,但for语句下面还有语句,还是会继续运行的。可以使用中断法,停止循环
for(int i=0;i<5000;i++){ if(this.interrupted()){ System.out.println("been stopped!"); throw new InterruptedException(); } System.out.print("i="+(i+1)); } System.out.println("under for");
9.线程在沉睡中停止会出现InterruptedException异常
10.方法stop()已经被作废,因为如果强制让线程停止,则有可能使一些清理性的工作得不到完成。
另外一个情况就是对锁定的对象进行了“解锁”,导致数据得不到同步的处理,出现数据不一致的问题。
11.使用return停止线程
while(true){ if(this.isInterrupted()){ System.out.println("stop!"); return ; } System.out.println("after while"); }
12.suspend(),resume()
在使用suspend与resume方法时,如果使用不当,极易造成公共的同步对象的独占,使得其他
13.yield方法
yield()方法的作用是放弃当前的CPU资源,将它让给其他的任务去占用CPU执行时间。但放弃的时间不确定,有可能刚刚放弃,马上又获得CPU时间片
14.守护线程Daemon
当进程中不存在非守护线程了,则守护线程自动销毁
15.在两个线程访问同一个对象中的同步方法时一定是线程安全的。
16.Synchronized锁重入
关键字Synchronized拥有锁重入的功能,也就是在使用Synchronized时,当一个线程得到一个对象锁后,再次请求此对象锁时是可以再次得到该对象的锁的。
17.出现异常,锁自动释放
18.同步不具有继承性,所以子类必须在继承的方法加上Synchronized关键字
19.使用synchronized(非 this 对象 x)同步代码块格式进行同步操作时,对象监视器必须是同一个对象。
20.关键字Synchronized还可以应用在static静态方法上,如果这样写,那是对当前的*.java文件对应的Class类进行持锁,Class锁可以对类的所有对象实例起作用
21.只要对象不变,即使对象的属性被改变,运行的结果还是同步。
22.线程安全包含原子性和可见性两个方面,Java的同步机制都是围绕这两个方面来确保线程安全的
23.等待/通知机制
在调用wait()之前,线程必须获得该对象的对象级别锁,即只能在同步方法或同步块中调用wait()方法。在执行wait()方法后,当前线程释放锁。
在从wait()返回前,线程与其他线程竞争重新获得锁
方法notify()也要在同步方法或同步块中,调用,即在调用前,线程也必须获得该对象的对象级别锁。
在执行notify()方法后,当前线程不会马上释放该对象锁,呈wait状态的线程也并不能马上获取该对象锁,要等到执行notify()方法的线程将程序执行完,也就是退出synchronized代码块后,当前线程才会释放锁。
每个锁对象都有两个队列,一个是就绪队列,一个是阻塞队列。就绪队列存储了将要获得锁的线程,阻塞队列存储了被阻塞的线程。一个线程被唤醒后,才会进入就绪队列,等待CPU调度;反之,一个线程被wait后,就会进入阻塞队列,等待下一次被唤醒。
当方法wait()被执行后,锁被自动释放,但执行完notify()方法,锁却不自动释放。
24.当线程呈wait()状态时,调用线程对象的interrupt()方法会出现InterruptedException异常。
25.带一个参数的wait(long)方法的功能是等待某一时间内是否有线程对锁进行唤醒,如果超过这个时间则自动唤醒。
26.处理生产者,消费者的关键点在于,使用while代替if语句对可能变化的条件进行判断,然后使用notifyAll()方法代替notify()方法,notifyAll()不光通知同类线程,也通知异类线程。
27.在很多情况下,主线程创建并启动子线程,如果子线程中要进行大量的耗时运算,主线程往往将早于子线程结束之前结束。
这时,如果主线程想等待子线程执行完成之后再结束,比如子线程处理一个数据,主线程要取得这个数据中的值,就要用到join()方法了,方法join()的作用是等待线程对象销毁。
28.在join过程中,如果当前线程对象被中断,则当前线程出现异常。
29.join(long)可以设定等待的时间
30.join(long)和sleep(long)的区别
方法join(long)的功能在内部是使用wait(long)方法来实现的,所以join(long)方法具有释放锁的特点。
Thread.sleep(long)方法不释放锁。
31.ThreadLocal可以实现每一个线程都有自己的共享变量。
ThreadLocal类接口很简单,只有4个方法,我们先来了解一下:
- void set(Object value)设置当前线程的线程局部变量的值。
- public Object get()该方法返回当前线程所对应的线程局部变量。
- public void remove()将当前线程局部变量的值删除,目的是为了减少内存的占用,该方法是JDK 5.0新增的方法。需要指出的是,当线程结束后,对应该线程的局部变量将自动被垃圾回收,所以显式调用该方法清除线程的局部变量并不是必须的操作,但它可以加快内存回收的速度。
- protected Object initialValue()返回该线程局部变量的初始值,该方法是一个protected的方法,显然是为了让子类覆盖而设计的。这个方法是一个延迟调用方法,在线程第1次调用get()或set(Object)时才执行,并且仅执行1次。ThreadLocal中的缺省实现直接返回一个null。
32.ReentrantLock——lock(),unlock(),newCondition()
33. Condition——await(),signal()
34.公平锁与非公平锁
公平锁表示线程获取锁的顺序是按照线程加锁的顺序来分配的,而非公平锁就是一种获取锁的抢占机制,是随机获得锁的。
创建公平锁:ReentrantLock lock = new ReentrantLock(true)
35.getHoldCount()——查询当前线程保持此锁定的个数(获取锁后再调用受相同锁控制的方法)
36.getQueueLength()——返回正等待获取此锁定的线程估计数
37.getWaitQueueLength(Condition condition)——返回等待与此锁定相关的给定条件Condition的线程估计数
38.boolean hasQueuedThread(Thread thread)——查询指定的线程是否在等待获取此锁定,boolean hasQueuedThreads()
39.boolean hasWaiters(Condition condition)——查询是否有线程正在等待与此锁定有关的condition条件
40.boolean isHeldByCurrentThread()——查询当前线程是否保持此锁定
41.boolean isLocked()——查询此锁定是否由任意线程保持
42.lockInterruptibly()——如果当前线程未被中断,则获取锁定,如果已经被中断则出现异常
当通过lockInterruptibly()方法获取某个锁时,如果不能获取到,只有进行等待的情况下,是可以响应中断的。
而用synchronized修饰的话,当一个线程处于等待某个锁的状态,是无法被中断的,只有一直等待下去。
43.tryLock()——仅在调用时锁定未被另一个线程保持的情况下,才获取该锁定。
44.condition.awaitUninterruptibly()——不能被中断
45.condition.awaitUntil(time)——如果没有其他线程唤醒,到达指定时间time后,自动进行唤醒。
46.ReentrantReadWriteLock——共享锁和排他锁。
lock.readLock().lock(),lock.writeLock().lock()
47.定时器
Timer类的主要作用就是设置计划任务,但封装任务的类却是TimerTask类。
schedule(TimerTask task, Date time)——在指定的日期执行一次某任务
创建一个Timer就是启动一个新的线程,那么这个新启动的线程并不是守护线程,而是一直在运行
public static void main(String[] args) throws InterruptedException { // TODO Auto-generated method stub Calendar cal = Calendar.getInstance(); cal.add(Calendar.SECOND, 3); MyTask task = new MyTask(); Timer timer=new Timer(true); timer.schedule(task, cal.getTime()); Thread.sleep(5000); }
如果执行任务的时间早于当前时间,则立即执行task任务
48.Timer中允许有多个TimerTask任务及延时的测试,其中TimerTask是以队列的方式一个一个被顺序地执行
49.TimerTask类的cancel()方法:作用是将自身从任务队列中进行清除
50.Timer类的cancel()方法:将任务队列中全部的任务进行清空。
51.schedule和scheduleAtFixedRate主要的区别只在于有没有追赶特性
对于延时任务,两者下一次任务的执行时间都是以上一次任务“结束”时的时间作为参考来计算,并没有运行效果上的区别,