java并发编程四 synchronized锁对象分析和变量线程线程安全分析

发布时间:2023年12月21日

线程八锁

所谓的“线程八锁”,其实就是考察 synchronized 锁住的是哪个对象
情况1:12 或 21

 @Slf4j(topic = "c.Number")
 class Number{
 public synchronized void a() {
 log.debug("1");
    }
 public synchronized void b() {
 log.debug("2");
    }
 }
 public static void main(String[] args) {
 Number n1 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n1.b(); }).start();
 }

情况2:1s后12,或 2 1s后 1

 @Slf4j(topic = "c.Number")
 class Number{
 public synchronized void a() {
 sleep(1);
 log.debug("1");
    }
 public synchronized void b() {
 log.debug("2");
    }
 }
 public static void main(String[] args) {
 Number n1 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n1.b(); }).start();
 }

情况3:3 1s 12 或 23 1s 1 或 32 1s 1

 @Slf4j(topic = "c.Number")
class Number{
 public synchronized void a() {
 sleep(1);
 log.debug("1");
    }
 public synchronized void b() {
 log.debug("2");
    }
 public void c() {
 log.debug("3");
    }
 }
 public static void main(String[] args) {
 Number n1 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n1.b(); }).start();
 new Thread(()->{ n1.c(); }).start();
 }

情况4:2 1s 后 1

 @Slf4j(topic = "c.Number")
 class Number{
 public synchronized void a() {
 sleep(1);
 log.debug("1");
    }
 public synchronized void b() {
 log.debug("2");
    }
 }
 public static void main(String[] args) {
 Number n1 = new Number();
 Number n2 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n2.b(); }).start();
 }

情况5:2 1s 后 1

 @Slf4j(topic = "c.Number")
 class Number{
 public static synchronized void a() {
 sleep(1);
 log.debug("1");
    }
 public synchronized void b() {
 log.debug("2");
    }

}
 public static void main(String[] args) {
 Number n1 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n1.b(); }).start();
 }

情况6:1s 后12, 或 2 1s后 1

 @Slf4j(topic = "c.Number")
 class Number{
 public static synchronized void a() {
 sleep(1);
 log.debug("1");
    }
 public static synchronized void b() {
 log.debug("2");
    }
 }
 public static void main(String[] args) {
 Number n1 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n1.b(); }).start();
 }

情况7:2 1s 后 1

 @Slf4j(topic = "c.Number")
 class Number{
 public static synchronized void a() {
 sleep(1);
 log.debug("1");
    }
 public synchronized void b() {
 log.debug("2");
    }
 }
 public static void main(String[] args) {
 Number n1 = new Number();
 Number n2 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n2.b(); }).start();
 }

情况8:1s 后12, 或 2 1s后 1

 @Slf4j(topic = "c.Number")
class Number{
 public static synchronized void a() {
 sleep(1);
 log.debug("1");
    }
 public static synchronized void b() {
 log.debug("2");
    }
 }
 public static void main(String[] args) {
 Number n1 = new Number();
 Number n2 = new Number();
 new Thread(()->{ n1.a(); }).start();
 new Thread(()->{ n2.b(); }).start();
 }

变量的线程安全分析

成员变量和静态变量是否线程安全?

  • 如果它们没有共享,则线程安全
  • 如果它们被共享了,根据它们的状态是否能够改变,又分两种情况
    • 如果只有读操作,则线程安全
    • 如果有读写操作,则这段代码是临界区,需要考虑线程安全

局部变量是否线程安全?

  • 局部变量是线程安全的
  • 但局部变量引用的对象则未必
    • 如果该对象没有逃离方法的作用访问,它是线程安全的
    • 如果该对象逃离方法的作用范围,需要考虑线程安全

常见线程安全类

  • String
  • Integer
  • StringBuffer
  • Random
  • Vector
  • Hashtable
  • java.util.concurrent 包下的类

这里说它们是线程安全的是指,多个线程调用它们同一个实例的某个方法时,是线程安全的。

文章来源:https://blog.csdn.net/studycodeday/article/details/135099493
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。