JUC并发编程

wait/sleep区别

来自不同的类

wait->object

sleep->Thread

 

wait会释放锁

sleep会抱着锁睡觉

Synchronized和Lock区别

 

 

.notifyAll();通知其他线程
.wait();等待 (会释放锁)


(if改为while防止虚假唤醒)
package lock;

import java.util.concurrent.locks.Lock;

public class demo1 {
public static void main(String[] args) {
Data data=new Data();
new Thread(()->{
for (int i = 0; i <10; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"A").start();
new Thread(()->{
for (int i = 0; i <10; i++) {
try {
data.Decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"B").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.increment();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"C").start();
new Thread(()->{
for (int i = 0; i <10 ; i++) {
try {
data.Decrement();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"D").start();

}
}
class Data{
private int number=0;
public synchronized void increment() throws InterruptedException {
if (number!=0){//0
this.wait();//等待
}
number++;//加1
System.out.println(Thread.currentThread().getName()+"->"+number);//获取当前线程的名字跟数量
this.notifyAll();//通知其他线程加一完毕

}
public synchronized void Decrement() throws InterruptedException {
if (number==0){
this.wait();//等待
}
number--;//减一
System.out.println(Thread.currentThread().getName()+"->"+number);//获取当前线程的名字跟数量
this.notifyAll();//通知其他线程减一完毕

}
}

拿两个加法线程A、B来说,比如A先执行,执行时调用了wait方法,那它会等待,此时会释放锁,那么线程B获得锁并且也会执行wait方法,两个加线程一起等待被唤醒。
此时减线程中的某一个线程执行完毕并且唤醒了这俩加线程,那么这俩加线程不会一起执行,其中A获取了锁并且加1,执行完毕之后B再执行。如果是if的话,那么A修改完num后,
B不会再去判断num的值,直接会给num+1。如果是while的话,A执行完之后,B还会去判断num的值,因此就不会执行。

 

 

8锁现象:

8锁的理解:

1.这么说吧,如果两个都是普通方法,那么就看谁先调用,一般先调用先执行
2.如果都是普通方法,但是有加延时,那么就延时少的先调用(因为时间是差不多同时调用,但是一个延时4秒再执行,一个延时2秒再执行,肯定2秒的先执行出来)
3.如果加锁的话,无延时,仍然是谁先调用谁执行
4.如果加锁加延时的话,延时不管,谁先调用谁执行,管它延不延时,反正没执行完不出来,这就是锁的作用
锁的是对象,没结束,锁不释放
5.两个对象,两把锁,不存在锁的情况,谁延时少谁执行(跟两个普通方法一样)

6.增加两个静态的同步方法,只有一个对象,先打印 发短信?打电话?
* 6、两个对象!增加两个静态的同步方法, 先打印 发短信?打电话?

都是发短信,因为锁的是类,不管是一个对象还是两个对象,反正锁的都是该类,只要锁的对象相同,就会被锁。

* 7、1个静态的同步方法,1个普通的同步方法 ,一个对象,先打印 发短信?打电话?
先打电话。因为静态锁的是类,普通锁的是对象,不是同个东西。
* 8、1个静态的同步方法,1个普通的同步方法 ,两个对象,先打印 发短信?打电话?
一样道理,一个锁的是对象,一个锁的是类,不是同个东西,相当于没锁,直接看延时。

java.util.ConcurrentModificationException并发修改异常!

vector用的synchronized效率太慢

cow用的lock锁效率快

 

 

 p12

posted @ 2021-10-25 01:06  爱笙灬  阅读(31)  评论(0)    收藏  举报