Java Thread总结
创建Thread:
通过继承Thread类或者实现Runnable接口,复写run()方法
优缺点:
继承Thread类时可以在run()方法中使用Thread类的方法(如interrupt())
实现Runnable接口时可以继承其他类;更好的处理threading pooling、task scheduling、timing问题
启动Thread:
通过调用Thread的start()方法
挂起Thread:
通过Thread.sleep()方法
检查Thread是否执行完毕:
Thread.isAlive(); // 当run()方法执行完后此方法返回false
立即停止(中断)Thread
调用Thread.interrupt();
在线程中检查Thread.isInterrupted()进行状态判断
判断当前的Thread
Thread.currentThread();
例如在run()方法中通过if(Thread.currentThread()!=this){}来判断是通过Thread.start()方法开启线程后执行的,还是在其他线程中直接通过Thread.run()调用的
Synchronized关键字:
当一个方法被声明为synchronized时,在同一时间只能有一个线程执行此方法。要执行此方法的线程必须先取得一个token,每个对象只有一个token,当多个线程想要执行某个对象的synchronized方法时,一个线程会抢到token(同步锁),执行方法,然后释放token。(锁是跟在特定的对象实例上的而不是某个方法或者某个类上的。在任意时间点对于任意对象来说,可以执行任意数目的方法,但是仅有一个synchronized方法可以执行)
可以自定义作用域(类似Lock)
synchronized(this){//do something}
Volatile关键字:
当一个变量被标示为Volatile,每次使用该变量时都必须从主存储器中读取;相同的,每次要写入该变量时,值都必须存入主存储器。(Java中允许thread在寄存器中存储变量的值,这样的话当某一个线程改变该变量的值时,别的线程可能不会察觉该变量值的变化)
将数组声明为volatile会让数组的引用变成volatile,而数组中的元素不是volatile,没有方法可以指定数组的元素应该以volatile的方式来处理
Thread.sleep()方法在执行过程中并不会释放该线程所占有的锁
Lock接口:
ReentrantLock 重入锁
ReentrantLock(boolean); //这个构造方法可以指定是否要以“公平”的形式发出lock,这里的“公平”被定义为先进先出。
lock(); // 获取锁
unlock(); // 释放锁
Lock:Java并不是盲目地在进入synchronized程序代码时就撷取lock。如果当前的thread已经占有lock,就不会再等待lock释放掉或者去撷取lock,而是让synchronized程序段运行就好了。
Thread Notification:
wait();
wait(long timeout);
notify();
notifyAll();
调用
wait()
和notify()
的方法必须是synchronized
的(包括run()
方法),并且synchronized
中的对象和调用wait()
和notify()
方法的对象必须是同一个
wait()
方法会释放同步锁,当收到notify()
时重新获得,因此可以用wait()
替代sleep()
,以等待notify()
当notify()
被调用时如果没有线程正在等待,函数将会直接返回,同时通知被丢弃
notifyAll()
可以对正在等待的所有线程发出通知,但是线程只是接到通知却并不能全部马上运行,因为只有一个能够获取对象锁
只可用于synchronized
锁范围内
// 通过使用不同对象的锁,可以在同一时间让更多的线程去访问不同的方法
private Object objLock = new Object();
public void run(){
synchronized(objLock){
if(done){
objLock.wait();
}else{
//do something
objLock.wait(200);
}
}
}
public void setDone(boolean b){
synchronized(objLock){
done=b;
if(!done){
objLock.notify();
}
}
}
使用Condition变量进行通知:
await(); –>wait();
await(long, TimeUnit); –>wait(long)
signal(); –>notify();
signalAll(); –>notifyAll();
awaitUninterruptibly();
awaitNanos(long nanosTimeout);
awaitUtil(Data);
Lock lock = new ReentrantLock();
Condition cv = lock.newCondition();//一个锁可以生成多个condition
lock.lock();//condition变量必须在生成它的锁的锁定范围内使用
while(true){
if(done){
cv.await();
}else{
//do something
cv.await(WAIT_TIME, TimeUnit.MILLISECONDS);
}
}
lock.unlock();