欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

Java~使用synchronized修饰静态方法带来的问题 与 同步synchronized代码块不使用String作为锁对象的原因

程序员文章站 2022-03-26 09:48:49
文章目录使用synchronized修饰静态方法带来的问题同步synchronized代码块不使用String作为锁对象的原因使用synchronized修饰静态方法带来的问题直接上代码/** * Created with IntelliJ IDEA. * Description: If you don't work hard, you will a loser. * User: Listen-Y. * Date: 2020-09-29 * Time: 11:39 */public...



使用synchronized修饰静态方法带来的问题

  • 直接上代码
/**
 * Created with IntelliJ IDEA.
 * Description: If you don't work hard, you will a loser.
 * User: Listen-Y.
 * Date: 2020-09-29
 * Time: 11:39
 */ public class ServiceStatic { public synchronized static void printA() { System.out.println(System.currentTimeMillis() + "进入printA_Static"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis() + "离开printA_Static"); } public synchronized static void printB() { System.out.println(System.currentTimeMillis() + "进入printB_Static"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis() + "离开printB_Static"); } public void printC() { System.out.println(System.currentTimeMillis() + "进入printC"); try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(System.currentTimeMillis() + "离开printC"); } } 
import javax.net.ssl.SSLContext; /**
 * Created with IntelliJ IDEA.
 * Description: If you don't work hard, you will a loser.
 * User: Listen-Y.
 * Date: 2020-09-29
 * Time: 11:41
 */ public class Run5 { public static void main(String[] args) { Thread thread = new Thread("A") { @Override public void run() { while (true) { ServiceStatic.printA(); } } }; Thread thread1 = new Thread("B") { @Override public void run() { while (true) { ServiceStatic.printB(); } } }; ServiceStatic serviceStatic = new ServiceStatic(); Thread thread2 = new Thread("C") { @Override public void run() { while (true) { serviceStatic.printC(); } } }; thread.start(); thread1.start(); thread2.start(); } } 
  • 运行结果
1601380417431进入printA_Static 1601380417431进入printC 1601380417531离开printA_Static 1601380417531离开printC 1601380417531进入printC 1601380417531进入printA_Static 1601380417631离开printC 1601380417631进入printC 1601380417632离开printA_Static 1601380417632进入printA_Static 1601380417732离开printC 1601380417732进入printC 1601380417733离开printA_Static 1601380417733进入printB_Static 1601380417832离开printC 1601380417832进入printC 1601380417833离开printB_Static 1601380417833进入printB_Static 1601380417932离开printC 1601380417932进入printC 
  • 观察我们发现虽然我们给三个方法printA printB printC 都上了锁, 但是运行结果却是printA与printB是同步的, 与printC是异步的
  • 这就是给static方法上锁带来的问题, 其实异步的原因是持有不同的锁, 一个是实例对象锁, 一个是类对象锁, 而且类对象锁可以对所有对象实例起到作用, 而printC是只对调用这个方法的那个实例对象其作用

同步synchronized代码块不使用String作为锁对象的原因

  • 直接上代码
public class Service { public void printStr(String str) { //给Str上锁 synchronized (str) { while (true) { System.out.println(Thread.currentThread().getName()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } } 
public class ThreadA extends Thread { private Service service; public ThreadA(Service service) { this.service = service; } @Override public void run() { service.printStr("Listen"); } } class ThreadB extends Thread { private Service service; public ThreadB(Service service) { this.service = service; } @Override public void run() { service.printStr("Listen"); } } 
public class Run4 { public static void main(String[] args) { Service service = new Service(); //创建俩个线程去执行 ThreadA threadA = new ThreadA(service); threadA.setName("A"); ThreadB threadB = new ThreadB(service); threadB.setName("B"); threadA.start(); threadB.start(); } } 
  • 运行结果
A
A
A
A
A
A

Process finished with exit code -1 
  • 分析结果我们发现, A和B俩个线程都启动了, 但是B线程一直没有得到执行, 也就是B线程一直没有获得锁
  • 这就是使用String作为锁对象带来的问题, 原因就是JVM中有String常量池缓存的功能, 看下面代码示例
public class Test { public static void main(String[] args) { String s = "Listen"; String s1 = "Listen"; System.out.println(s==s1); } } 
true 
  • 由此我们得出, 虽然线程A和线程B传入的不是同一个引用的字符串, 但是这个String对象却是同一个, 也就是上的其实是同一把锁.

本文地址:https://blog.csdn.net/Shangxingya/article/details/108874746