对使用Synchronized的一些建议

本文提供了关于Java中Synchronized关键字使用的建议,包括如何避免阻塞操作、选择合适的同步对象等。同时,也讨论了直接使用JDBCAPI进行数据库操作的几个主要缺点,比如业务逻辑与数据库访问代码混合等问题。

* 对使用Synchronized的一些建议

1、不要在同步代码段调用其它的同步方法。(很难做到,尽量避免)

2、不要在同步代码段中调用容易导致阻塞的操作。

3、仔细分析同步对象,尽可能缩小同步代码段。

4、仔细选择同步对象。

* 直接使用JDBC API的缺点

1、业务逻辑的代码和数据库访问搀杂在一起,程序结构不清晰。

2、在程序代码中嵌入面向关系的SQL语句,不能完全的运用面向对象的思维。

3、业务逻辑和关系数据模型绑定。(如当业务逻辑中的代码要修改的时候,数据库中表要改,SQL语句也要改)

4、如果SQL语句有错误,编译时不能检查。

`Synchronized` 是 Java 中用于实现线程同步的关键字,主要用于控制多个线程对共享资源的访问,确保在同一时刻只有一个线程可以执行某个代码块或方法,从而避免线程安全问题。 --- ## 一、`synchronized` 的使用方式 ### 1. **修饰实例方法** 锁对象是当前类的实例对象(`this`)。 ```java public class SynchronizedExample { public synchronized void method() { // 同步代码 System.out.println(Thread.currentThread().getName() + " is running"); } } ``` - **锁对象**:当前实例对象 `this`。 - **适用场景**:多个线程访问同一个对象的同步方法时,会串行执行。 --- ### 2. **修饰静态方法** 锁对象是当前类的 Class 对象(`类名.class`)。 ```java public class SynchronizedExample { public static synchronized void staticMethod() { // 同步代码 System.out.println(Thread.currentThread().getName() + " is running static method"); } } ``` - **锁对象**:`SynchronizedExample.class`。 - **适用场景**:多个线程访问同一个类的同实例的静态同步方法时,也会串行执行。 --- ### 3. **修饰代码块(推荐)** 可以指定锁对象,灵活性更高。 ```java public class SynchronizedExample { private final Object lock = new Object(); public void blockMethod() { synchronized (lock) { // 同步代码块 System.out.println(Thread.currentThread().getName() + " is in synchronized block"); } } } ``` - **锁对象**:可以是任意对象,建议使用私有对象,防止外部修改锁对象。 - **优点**: - 控制粒度更细,提高并发性能。 - 避免锁整个方法,只锁关键代码。 --- ## 二、synchronized 的锁机制 ### 1. **可重性** `synchronized` 是可重锁,同一个线程可以多次获取同一个锁。 ```java public class ReentrantExample { public synchronized void methodA() { System.out.println("methodA"); methodB(); // 可以再次进 } public synchronized void methodB() { System.out.println("methodB"); } } ``` ### 2. **可中断性** 一旦线程进等待锁的状态,除非获得锁,否则无法被中断。 ### 3. **非公平锁** `synchronized` 是非公平锁,JVM 保证等待时间最长的线程优先获取锁。 --- ## 三、synchronized 的底层实现原理 `synchronized` 的底层是通过 **Monitor(监视器)** 实现的,每个对象都有一个关联的 Monitor。 - 当线程进 `synchronized` 代码块时,会尝试获取对象的 Monitor。 - 如果 Monitor 的计数器为 0,线程获取锁,Monitor 计数器加 1。 - 如果 Monitor 被其他线程持有,当前线程会被阻塞,直到 Monitor 被释放。 - 持有 Monitor 的线程退出同步代码块后,Monitor 计数器减 1。 --- ## 四、使用建议 | 使用方式 | 推荐程度 | 说明 | |------------------|----------|------| | 同步代码块 | ⭐⭐⭐⭐⭐ | 推荐使用,锁粒度细,性能好 | | 同步方法 | ⭐⭐⭐⭐ | 可用,但锁粒度较大 | | 同步静态方法 | ⭐⭐⭐ | 用于类级别的同步 | --- ## 五、示例:生产者消费者模型(使用 synchronized) ```java class SharedResource { private int data; private boolean available = false; public synchronized void put(int value) { while (available) { try { wait(); // 等待消费者消费 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } data = value; available = true; notify(); // 唤醒消费者 } public synchronized int get() { while (!available) { try { wait(); // 等待生产者生产 } catch (InterruptedException e) { Thread.currentThread().interrupt(); } } available = false; notify(); // 唤醒生产者 return data; } } public class ProducerConsumerExample { public static void main(String[] args) { SharedResource resource = new SharedResource(); Thread producer = new Thread(() -> { for (int i = 1; i <= 5; i++) { resource.put(i); System.out.println("Produced: " + i); } }); Thread consumer = new Thread(() -> { for (int i = 1; i <= 5; i++) { int value = resource.get(); System.out.println("Consumed: " + value); } }); producer.start(); consumer.start(); } } ``` --- ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值