1、synchronized锁的修饰的是方法和块
2、synchronized锁修饰静态方法就是类锁;修饰非静态方法就是对象锁。
3、类锁:是如果有N个静态的方法被synchronized修饰,有一个线程执行其中一个加锁的静态方法,那么其他的线程就无法继续调用这个类中的其他的加锁的静态方法,直到这个静态方法被执行完,其他加锁静态方法才可以被执行。不加锁的方法是不受影响的。
4、对象锁:在java中,类中定义一个非静态的方法,如果需要在其他类中使用这个方法,我们就要在其他类中,new一个新的对象。对象锁的意义是,synchronized锁修饰的一个非静态方法在被new的对象调用时,这个对象调用的其他的synchronized修饰非静态方法,是无法执行的,直到正在被调用的方法执行完毕。但是不同的对象之间是互不影响的。
5、类锁和对象锁是互不影响的。
6、如果想要主线程中的方法,在子线程执行完毕之后在执行通过 t1.join();
public static void main(String[] ages){
Thread t1=new Thread(){
public void run(){
}
};
Thread t2=new Thread(){
public void run(){
}
};
t1.start();
t2.start();
t1.join();
t2.join();
System.out.println();
}
7、加锁也并一定能完全保证结果的正确,最重要的是读写顺序问题;一个线程在写完毕后并且刷新回去,然后另一个线程,保证读取到的是刷新以后的数据,在此基础上进行计算,才可以保证数据的正确性。
8、场景展示
public class Person {
private int money=0;
public synchronized void m1(int x) {
money += x;
}
public synchronized int getMoney() {
return money;
}
public synchronized void setMoney(int x) {
money = x;
}
}public class Test{
public static void main(String[] ages){
Person a1=new Person();
Person a2=new Person();
Thread t1=new Thread() {
public void run() {
for(int i=0;i<10000;i++) {
a1.m1(1);//可以
//----------------
int x=a1.getMoney()+1;//不可以
a1.setMoney(x);
}
//Person.m3("线程3");
}
};
Thread t2=new Thread() {
public void run() {
for(int i=0;i<10000;i++) {
a1.m1(1);//可以
//----------------------
int x=a1.getMoney()+1;//不可以
a1.setMoney(x);
}
}
};
t1.start();
t2.start();
}
}
以上我们可知m1方法中进行的是读写操作,在读取money并进行修改后,在m1方法中直接写回到内存中,才会是解除synchronized锁。
而第二个方法是用了两个synchronized锁的方法,当其中一个执行完毕后,就会解除锁,此时其他的线程就很有可能占用锁。
————————————————
版权声明:本文为CSDN博主「三思守心」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_61353850/article/details/123596954