synchronized锁

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锁的方法,当其中一个执行完毕后,就会解除锁,此时其他的线程就很有可能占用锁。

你可能感兴趣的:(系统安全)