java 同步锁(synchronized)的正确使用姿势

关于线程安全,线程锁我们经常会用到,但你的使用姿势正确不,反正我用错了好长一段时间而不自知。所以有了这篇博客总结下线程锁的正确打开姿势 废话不说看例子 一,对整个方法进行加锁 1,对整个方法进行加锁,不同线程访问同一个类的同一个对象

public class TestRunnable implements Runnable {

	@Override
	public synchronized  void run() {
		// TODO Auto-generated method stub
			for(int i=0;i<10;i++)
			{
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"---"+i);
			}
		}
	

}
public static void main(String[] args)
 {
 TestRunnable runnable=new TestRunnable();
 Thread threadA=new Thread(runnable,"threadA");
 threadA.start();
 
 Thread threadB=new Thread(runnable,"threadB");
 threadB.start();
 }

运行结果: threadA—0

threadA—1

threadA—2

threadA—3

threadA—4

threadA—5

threadA—6

threadA—7

threadA—8

threadA—9

threadB—0

threadB—1

threadB—2

threadB—3

threadB—4

threadB—5

threadB—6

threadB—7

threadB—8

threadB—9

2,对整个方法进行加锁,不同线程访问同一个类的不同对象

public class TestRunnable implements Runnable {

	@Override
	public synchronized  void run() {
		// TODO Auto-generated method stub
			for(int i=0;i<10;i++)
			{
				try {
					Thread.sleep(200);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"---"+i);
			}
		}
	

}
 public static void main(String[] args)
 {
 TestRunnable runnableA=new TestRunnable();
 Thread threadA=new Thread(runnableA,"threadA");
 threadA.start();
 
 TestRunnable runnableB=new TestRunnable();
 Thread threadB=new Thread(runnableB,"threadB");
 threadB.start();
 }

运行结果: threadB—0

threadA—0

threadA—1

threadB—1

threadA—2

threadB—2

threadA—3

threadB—3

threadB—4

threadA—4

threadA—5

threadB—5

threadA—6

threadB—6

threadA—7

threadB—7

threadA—8

threadB—8

threadA—9

threadB—9

小结:对方法整体加锁的做法适用条件是 多个线程访问的必须是同一个类的同一个实例对象

一,对代码块进行加锁 1,对代码块进行加锁,加锁对象为当前类对象,不同线程访问同一个类的同一个对象

public class TestRunnable implements Runnable {


 @Override
 public void run() {
 // TODO Auto-generated method stub
 synchronized (TestRunnable.this) {
 for (int i = 0; i < 10; i++) {
 try {
 Thread.sleep(200);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 System.out.println(Thread.currentThread().getName() + "---" + i);
 }
 }
 }


}
public static void main(String[] args)
 {
 TestRunnable runnable=new TestRunnable();
 Thread threadA=new Thread(runnable,"threadA");
 threadA.start();
 
 Thread threadB=new Thread(runnable,"threadB");
 threadB.start();
 }

运行结果: threadA—0

threadA—1

threadA—2

threadA—3

threadA—4

threadA—5

threadA—6

threadA—7

threadA—8

threadA—9

threadB—0

threadB—1

threadB—2

threadB—3

threadB—4

threadB—5

threadB—6

threadB—7

threadB—8

threadB—9

2,对代码块进行加锁,加锁对象为当前类对象,不同线程访问同一个类的不同对象

public class TestRunnable implements Runnable {


 @Override
 public void run() {
 // TODO Auto-generated method stub
 synchronized (TestRunnable.this) {
 for (int i = 0; i < 10; i++) {
 try {
 Thread.sleep(200);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 System.out.println(Thread.currentThread().getName() + "---" + i);
 }
 }
 }


}
 public static void main(String[] args)
 {
 TestRunnable runnableA=new TestRunnable();
 Thread threadA=new Thread(runnableA,"threadA");
 threadA.start();
 
 TestRunnable runnableB=new TestRunnable();
 Thread threadB=new Thread(runnableB,"threadB");
 threadB.start();
 }

运行结果: threadB—0

threadA—0

threadB—1

threadA—1

threadB—2

threadA—2

threadA—3

threadB—3

threadA—4

threadB—4

threadB—5

threadA—5

threadA—6

threadB—6

threadB—7

threadA—7

threadA—8

threadB—8

threadA—9

threadB—9

3,对代码块进行加锁,加锁对象为当前类(不是类对象哦),不同线程访问同一个类的同一个对象

public class TestRunnable implements Runnable {


 @Override
 public void run() {
 // TODO Auto-generated method stub
 synchronized (TestRunnable.class) {
 for (int i = 0; i < 10; i++) {
 try {
 Thread.sleep(200);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 System.out.println(Thread.currentThread().getName() + "---" + i);
 }
 }
 }


}
public static void main(String[] args)
 {
 TestRunnable runnable=new TestRunnable();
 Thread threadA=new Thread(runnable,"threadA");
 threadA.start();
 
 Thread threadB=new Thread(runnable,"threadB");
 threadB.start();
 }

运行结果: threadA—0

threadA—1

threadA—2

threadA—3

threadA—4

threadA—5

threadA—6

threadA—7

threadA—8

threadA—9

threadB—0

threadB—1

threadB—2

threadB—3

threadB—4

threadB—5

threadB—6

threadB—7

threadB—8

threadB—9

4,对代码块进行加锁,加锁对象为当前类(不是类对象哦),不同线程访问同一个类的不同对象

public class TestRunnable implements Runnable {


 @Override
 public void run() {
 // TODO Auto-generated method stub
 synchronized (TestRunnable.class) {
 for (int i = 0; i < 10; i++) {
 try {
 Thread.sleep(200);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 System.out.println(Thread.currentThread().getName() + "---" + i);
 }
 }
 }


}
 public static void main(String[] args)
 {
 TestRunnable runnableA=new TestRunnable();
 Thread threadA=new Thread(runnableA,"threadA");
 threadA.start();
 
 TestRunnable runnableB=new TestRunnable();
 Thread threadB=new Thread(runnableB,"threadB");
 threadB.start();
 }

运行结果: threadA—0

threadA—1

threadA—2

threadA—3

threadA—4

threadA—5

threadA—6

threadA—7

threadA—8

threadA—9

threadB—0

threadB—1

threadB—2

threadB—3

threadB—4

threadB—5

threadB—6

threadB—7

threadB—8

threadB—9

5,对代码块进行加锁,加锁对象为已赋值的变量,不同线程访问同一个类的同一个对象

public class TestRunnable implements Runnable {


 @Override
 public void run() {
 // TODO Auto-generated method stub
 synchronized ("test") {
 for (int i = 0; i < 10; i++) {
 try {
 Thread.sleep(200);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 System.out.println(Thread.currentThread().getName() + "---" + i);
 }
 }
 }


}
public static void main(String[] args)
 {
 TestRunnable runnable=new TestRunnable();
 Thread threadA=new Thread(runnable,"threadA");
 threadA.start();
 
 Thread threadB=new Thread(runnable,"threadB");
 threadB.start();
 }

运行结果: threadA—0

threadA—1

threadA—2

threadA—3

threadA—4

threadA—5

threadA—6

threadA—7

threadA—8

threadA—9

threadB—0

threadB—1

threadB—2

threadB—3

threadB—4

threadB—5

threadB—6

threadB—7

threadB—8

threadB—9

6,对代码块进行加锁,加锁对象为已赋值的变量,不同线程访问同一个类的不同对象

public class TestRunnable implements Runnable {


 @Override
 public void run() {
 // TODO Auto-generated method stub
 synchronized ("test") {
 for (int i = 0; i < 10; i++) {
 try {
 Thread.sleep(200);
 } catch (InterruptedException e) {
 // TODO Auto-generated catch block
 e.printStackTrace();
 }
 System.out.println(Thread.currentThread().getName() + "---" + i);
 }
 }
 }


}
 public static void main(String[] args)
 {
 TestRunnable runnableA=new TestRunnable();
 Thread threadA=new Thread(runnableA,"threadA");
 threadA.start();
 
 TestRunnable runnableB=new TestRunnable();
 Thread threadB=new Thread(runnableB,"threadB");
 threadB.start();
 }

运行结果: threadA—0

threadA—1

threadA—2

threadA—3

threadA—4

threadA—5

threadA—6

threadA—7

threadA—8

threadA—9

threadB—0

threadB—1

threadB—2

threadB—3

threadB—4

threadB—5

threadB—6

threadB—7

threadB—8

threadB—9

小结:当对代码块进行加锁时,当加锁对象是一个确定值时(当前类,或者已赋值的变量) 不同线程访问同一个类的不同对象时也可以实现线程同步

最后奉上线程锁在实际开发中的应用—-单例模式

1,懒汉式写法

public class Singleton {
    private static Singleton instance;
    private Singleton (){}
    public static synchronized Singleton getInstance() {
	if (instance == null) {
	    instance = new Singleton();
	}
	return instance;
    }
}

2,懒汉式写法升级版(双重校验锁) 性能优于第一种

public class Singleton {  
    private static Singleton singleton;  
    private Singleton (){}  
    public static Singleton getSingleton() {  
    if (singleton == null) {  
        synchronized (Singleton.class) {  
        if (singleton == null) {  
            singleton = new Singleton();  
        }  
        }  
    }  
    return singleton;  
    }  
} 

3,饿汉式写法,不依赖于线程同步锁,依赖于静态变量和类的同步加载实现线程安全

public class Singleton {
    private static Singleton instance = new Singleton();
    private Singleton (){}
    public static Singleton getInstance() {
	return instance;
    }
}

    原文作者:java锁
    原文地址: https://blog.csdn.net/AndroFarmer/article/details/69219066
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞