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

    xiaoxiao2021-03-25  58

    关于线程安全,线程锁我们经常会用到,但你的使用姿势正确不,反正我用错了好长一段时间而不自知。所以有了这篇博客总结下线程锁的正确打开姿势 废话不说看例子 一,对整个方法进行加锁 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; } }
    转载请注明原文地址: https://ju.6miu.com/read-35955.html

    最新回复(0)