1.A线程正在执行一个对象中的同步方法,B线程可以执行同一个对象的非同步方法,但是不能执行同对象的其他同步方法
2.线程抛出异常会释放锁--可catch异常回滚事务
3.volatile 修饰字段,一个线程修改该字段,会通知其他线程重新读取该字段 ,volatile保证了可见性,但是没有保证原子性,synchronized 既可以保证可见性,也能保证原子性;volatile比synchronized性能好,能用volatile就用volatile
4.Atomicxxxxxx类中的方法是原子性的,可见性的,但是多个方法间一起使用,方法间的间隙会产生非原子操作
5.synchronized锁住的是堆内存里的对象,而非栈上面的引用,当发生异常的时候,会释放锁,其他线程可执行;当变量指向一块新的对象时,其他线程可使用新的对象锁,见下面Demo
import java.util.concurrent.TimeUnit;
public class T5 {
private Object o = new Object();
public void m(){
synchronized (o){
while(true){
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
}
}
}
public static void main(String[] args) {
T5 t = new T5();
new Thread(t::m).start();
try {
TimeUnit.SECONDS.sleep(3);
} catch (InterruptedException e) {
e.printStackTrace();
}
t.o = new Object();
new Thread(t::m).start();
}
}
6.不要以字符串常量作为锁定对象,不然容易出现死锁,如果锁定的是字符串,这个字符串可能在常量池已经出现过并被其他线程锁住;这种情况使用起来就不知不觉的出现死锁;
7.成员方法上添加synchronized 等同于方法内添加synchronized(this){} ,锁住对象本身,而非一段代码;静态方法上添加synchronized等同于在静态方法内synchronized(xxx.class){},静态方法上加synchronized和成员方法上加synchronized两个方法不互斥
8.写加锁,读不加锁,容易出现脏读
9.一个线程执行一个同步方法时,方法中调用另一个同步方法,是可以的,这个线程申请了这个对象锁,当访问另一个同步方法时,再申请一次该对象锁,synchronized是可重入锁,访问结束,锁也会释放两次,同样子类的同步方法可以调用父类的同步方法
10.死锁Demo
public class DeadLock {
private Object o1 = new Object();
private Object o2 = new Object();
public void f1() throws InterruptedException {
synchronized(o1){
System.out.println(Thread.currentThread().getName()+"获得o1锁");
Thread.sleep(2000);
synchronized(o2){
System.out.println(Thread.currentThread().getName()+"获得o2锁");
}
}
}
public void f2() throws InterruptedException {
synchronized(o2){
System.out.println(Thread.currentThread().getName()+"获得o2锁");
Thread.sleep(2000);
synchronized(o1){
System.out.println(Thread.currentThread().getName()+"获得o1锁");
}
}
}
public static void main(String[] args) throws Exception{
DeadLock deadLock = new DeadLock();
new Thread(() -> {
try {
deadLock.f1();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
new Thread(() -> {
try {
deadLock.f2();
} catch (InterruptedException e) {
e.printStackTrace();
}
}).start();
}
}
11.细粒度的锁要比粗粒度的锁性能提高不少
12.wait方法百分99之情况都和while一起使用