private int count = 10;
private Object obj = new Object();
public void sub() {
synchronized (obj) {
count--;
}
}
上述代码中 synchronized 锁定的是 obj 这个对象;
private int count = 10;
public void sub() {
synchronized (this) {
count--;
}
}
上述代码中 synchronized 锁定的是 当前对象;
private int count = 10;
private Object obj = new Object();
public synchronized void sub() {
count--;
}
在方法上加锁,锁定的依然是当前对象,所以这种写法等同于上面;不过没有上面的写法灵活。
private static int count = 10;
public synchronized static void sub() {
count--;
}
在静态方法上加锁,锁定的是当前类的产品是一类对象;
public static void sub2() {
synchronized (Demo1.class) {
count--;
}
}
等同于上诉写法;
public synchronized void m1() {
count--;
m2(); // 可重入
}
public synchronized void m2() {
}
可以配合Atomic类使用;如 AtomicInteger
注意:Atomic类的多个方法同时使用时不保证原子性,单独使用时才能保证原子性
String str1 = "Hello";
String str2 = "Hello";
public void m1() {
synchronized (str1) {
count--;
}
}
public void m2() {
synchronized (str2) {
count--;
}
}
其实 str1 和 str2 底层是同一个对象;
public class MyContainer4 {
//添加volatile,使t2能够得到通知
volatile List lists = new ArrayList();
public void add(Object o) {
lists.add(o);
}
public int size() {
return lists.size();
}
public static void main(String[] args) {
MyContainer4 c = new MyContainer4();
final Object lock = new Object();
new Thread(() -> {
synchronized(lock) {
System.out.println("t2启动");
if(c.size() != 5) {
try {
lock.wait();
} catch (InterruptedException e) {
}
}
System.out.println("t2 结束");
//通知t1继续执行
lock.notify();
}
}, "t2").start();
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e1) {
}
new Thread(() -> {
System.out.println("t1启动");
synchronized(lock) {
for(int i=0; i<10; i++) {
c.add(new Object());
System.out.println("add " + i);
if(c.size() == 5) {
lock.notify();
//释放锁,让t2得以执行
try {
lock.wait();
} catch (InterruptedException e) {
}
}
try {
TimeUnit.SECONDS.sleep(1);
} catch (InterruptedException e) {
}
}
}
}, "t1").start();
}
}
// https://www.cnblogs.com/duanxz/p/5038471.html
public static void main(String[] args) {
long start = System.currentTimeMillis();
Object obj = new Object();
Thread thread1 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " start...");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//LockSupport.park();
synchronized (obj) {
try {
obj.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
System.out.println(Thread.currentThread().getName() + " over");
}, "thread1");
Thread thread2 = new Thread(() -> {
System.out.println(Thread.currentThread().getName() + " start,,,");
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
//LockSupport.unpark(thread1);
synchronized (obj) {
obj.notifyAll();
}
System.out.println(Thread.currentThread().getName() + " over");
}, "thread2");
thread1.start();
thread2.start();
try {
thread1.join();
thread2.join();
} catch (Exception e) {
throw new RuntimeException(e);
}
System.out.println(System.currentTimeMillis() - start);
}