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

本文通过实例解析线程八锁现象,讨论了不同情况下成员变量、静态变量和局部变量的线程安全问题,并列举了常见线程安全类的应用。

线程八锁

所谓的“线程八锁”,其实就是考察 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 包下的类

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

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

过去日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值