monitor
同一monitor阻塞,不同monitor互斥
synchronized(锁)
Java中每一个对象都可以作为锁,这是synchronized实现同步的基础:
普通同步方法(实例方法),锁是当前实例对象 ,进入同步代码前要获得当前实例的锁
静态同步方法,锁是当前类的class对象 ,进入同步代码前要获得当前类对象的锁
同步方法块,锁是括号里面的对象,对给定对象加锁,进入同步代码库前要获得给定对象的锁。
/**
* 对象锁,代码级别,同一对象争用该锁,this为SynMethod实例,synchronized的锁绑定在this对象上
*/
public void method1() {
synchronized (this) {
}
}
等于
/**
* 对象锁,方法级别,同一对象争用该锁,普通(非静态)方法,synchronized的锁绑定在调用该方法的对象上,与上一个写法含义一致
*/
public synchronized void method2() {
}
等于
/**
* 类锁,代码级别,同一类争用该锁
*/
public void method4() {
synchronized (SynMethod.class) {
}
}
wait,notify
private static class MyThread extends Thread {
private synchronized void initString() {
sharedString = "啦啦啦啦";
notifyAll();
}
@Override
public void run() {
super.run();
printString();
}
private synchronized void printString() {
while (sharedString == null) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("String: " + sharedString);
}
}
注意:一定要用while,因为InterruptedException会打断,代码会往下走
join
一个线程插入另一个线程,被插入线程相当于进入wait状态,在join线程执行完之后会自动调用notify方法
Thread.yield
降低当前线程执行优先级
lock
Lock lock = ...;
lock.lock();
try{
//处理任务
}catch(Exception ex){
}finally{
lock.unlock(); //释放锁
}
ReentrantReadWriteLock
ReentrantLock和synchronized基本上都是排它锁,意味着这些锁在同一时刻只允许一个线程进行访问,而读写锁在同一时刻可以允许多个读线程访问,在写线程访问的时候其他的读线程和写线程都会被阻塞。读写锁维护一对锁(读锁和写锁),通过锁的分离,使得并发性提高。
网友评论