JAVA synchronized用法总结

在Java中,synchronized关键字用来控制线程同步的,即在多线程的情况下,控制某段代码或某个方法不会被多个线程同时执行,从而避免修改某些静态变量的值,造成数据错误。

synchronized关键字的用法一般为 synchronized(this)、synchronized(Object)、在方法中使用synchronizedsynchronized(xxx.Class)。下面针对这四种参数以及其他条件分别来说synchronized关键字的作用。

一、当一个线程使用一个对象时

    ①.锁的方法为非静态方法

public class Test {
	public synchronized void test(){
			System.out.println("test start...");
			try{
				Thread.sleep(1000);
			}catch (Exception e) {
				e.printStackTrace();
			}
			System.out.println("test end...");
	}
}
public class MyThread extends Thread {
	public MyThread(){
		
	}
	
	public void run(){
		Test t = new Test();
		t.test();
	}
}
public class Main {

	public static void main(String[] args) {
		for(int i = 0; i < 3; i ++){
			Thread t = new MyThread();
			t.start();
		}
	}
}

JAVA synchronized用法总结_第1张图片

从输出结果可以看到,synchronized并没有起到任何作用,三个线程还是同时执行了。

如果把synchronized放到方法里面

public class Test {
	public void test(){
		synchronized(this){
			System.out.println("test start...");
			try{
				Thread.sleep(1000);
			}catch (Exception e) {
				e.printStackTrace();
			}
			System.out.println("test end...");
		}
	}
}

JAVA synchronized用法总结_第2张图片

synchronized依然没有起作用,如果使用非静态Object也是同样的结果。

但是,当使用静态Object时

public class Test {
	private static Object mLock = new Object();
	public void test(){
		synchronized (mLock) {
			System.out.println("test start...");
			try{
				Thread.sleep(1000);
			}catch (Exception e) {
				e.printStackTrace();
			}
			System.out.println("test end...");
		}
	}
}

JAVA synchronized用法总结_第3张图片

可以看到线程并没有同时执行。初步分析1.当参数为this、非静态Object或在方法中使用synchronized关键字时,由于一个线程对应的是一个对象,锁只是锁住了当前线程对应的对象,并没有对其他对象进行锁的处理;2.而当参数为静态Object时,此对象在类加载时就会被初始化,因此所有线程操作的是同一个对象。


public class Test {
	public void test(){
		synchronized (Test.class) {
			System.out.println("test start...");
			try{
				Thread.sleep(1000);
			}catch (Exception e) {
				e.printStackTrace();
			}
			System.out.println("test end...");
		}
	}
}

JAVA synchronized用法总结_第4张图片

但是当参数变为Test.class时,可以看到三个线程并没有同时执行。经查找资料,每个类在jvm中有唯一的字节码,在代码中体现为Test.class,即Test.class在jvm中是唯一的,无论多少对象,都会共用一把锁。

    ②.锁的方法为静态方法

public class Test {
	public static synchronized void test(){
		System.out.println("test start...");
		try{
			Thread.sleep(1000);
		}catch (Exception e) {
			e.printStackTrace();
		}
		System.out.println("test end...");
	}
}

JAVA synchronized用法总结_第5张图片

可以看到线程会进行阻塞后再执行。可以结合参数为静态Object时进行分析,其他情况(参数为this、class和在方法中使用)结果也均如此。

二、当多个线程使用一个对象时

可以预见到,无论是静态方法还是非静态方法同步锁都会起作用。

你可能感兴趣的:(JAVA synchronized用法总结)