当前位置: 首页 > wzjs >正文

网络营销的主要形式有建设网站兴安盟seo

网络营销的主要形式有建设网站,兴安盟seo,泉州网站公司,举例说明商业网站的建设流程1. synchronized 关键字 工作原理 对象锁:在Java中,每个对象都有一个与之关联的监视器锁(monitor lock)。当一个线程尝试进入由 synchronized 保护的代码块或方法时,它必须首先获取该对象的监视器锁。如果锁已经被其…

1. synchronized 关键字

工作原理
  • 对象锁:在Java中,每个对象都有一个与之关联的监视器锁(monitor lock)。当一个线程尝试进入由 synchronized 保护的代码块或方法时,它必须首先获取该对象的监视器锁。如果锁已经被其他线程持有,则该线程将被阻塞,直到锁被释放。
  • 类锁:对于静态同步方法来说,锁定的是这个类对应的Class对象,而不是实例对象。这意味着所有实例共享同一把锁。
内部机制
  • 对象头与Mark Word
    • 每个Java对象都有一个对象头,其中包含了Mark Word。根据不同的锁状态(无锁、偏向锁、轻量级锁、重量级锁),Mark Word的内容会发生变化。
      • 无锁状态:包含对象的哈希值或GC年龄。
      • 偏向锁状态:适用于单线程访问场景,减少不必要的CAS操作。偏向锁会在对象头中记录偏向的线程ID。如果后续请求依旧来自同一线程,则无需再次获取锁。
      • 轻量级锁状态:采用基于CAS的操作来尝试获取锁,避免直接进入重量级锁带来的性能损耗。轻量级锁通过在当前线程的栈帧中创建一个锁记录,并使用CAS操作尝试更新对象头中的Mark Word来实现。
      • 重量级锁状态:如果竞争加剧,JVM会将锁膨胀为重量级锁。此时涉及到操作系统层面的调度,线程会被挂起等待锁的释放。
  • 锁升级过程:包括偏向锁、轻量级锁到重量级锁的转换过程,旨在减少线程获取锁的成本。锁升级的过程是自动的,不需要开发者干预。偏向锁 -> 轻量级锁 -> 重量级锁的升级路径是为了优化性能,在低竞争条件下尽可能地减少开销。
特性
  • 自动管理:进入同步代码块或方法时自动获取锁,退出时自动释放锁,不需要手动操作。
  • 不可中断:一旦一个线程开始等待获取 synchronized 锁,则无法被中断,直到成功获得锁或当前线程结束。
  • 公平性:不保证获取锁的顺序,可能会导致某些线程长时间等待(饥饿现象)。
  • 支持重入:同一个线程可以多次获取同一个锁而不会造成死锁。这是通过计数器机制实现的,每次获取锁时计数器加一,释放锁时减一,当计数器归零时才真正释放锁。
  • 可见性和有序性:提供内存屏障功能,确保了一个线程对共享变量所做的修改,在其释放锁之后,能够立即对随后获取同一把锁的其他线程可见,并防止指令重排序。
示例代码
public class SynchronizedExample {private int count = 0;// 同步方法public synchronized void increment() {count++;}// 同步代码块public void incrementWithBlock() {synchronized (this) {count++;}}// 静态同步方法public static synchronized void staticIncrement(SynchronizedExample instance) {instance.count++;}// 使用双重检查锁定模式初始化单例private static volatile SynchronizedExample singletonInstance;//双重检查锁定模式是一种高效的单例实现方式,它结合了懒加载、线程安全和性能优化的优点。通过                 //volatile 和双重检查机制,可以确保在多线程环境下只创建一个实例,同时避免不必要的同步开销。public static SynchronizedExample getInstance() {if (singletonInstance == null) {synchronized (SynchronizedExample.class) {if (singletonInstance == null) {singletonInstance = new SynchronizedExample();}}}return singletonInstance;}
}

双重检查锁定模式详解

为什么需要双重检查锁定?
  1. 性能优化:如果直接使用 synchronized 方法或代码块进行单例初始化,每次访问实例时都会进入同步代码块,这会导致性能开销较大。
  2. 懒加载:只有在第一次访问实例时才进行初始化,而不是在类加载时就创建实例。
  3. 线程安全:确保多个线程同时访问时不会创建多个实例。

双重检查锁定的核心思想是:

  • 在第一次检查 singletonInstance == null 时,避免进入同步块。
  • 在第二次检查 singletonInstance == null 时,确保只有一个线程能够创建实例。
实现步骤
  1. 第一次检查:在获取锁之前,先检查实例是否已经存在。如果已经存在,则直接返回实例,避免进入同步块。
  2. 加锁:如果实例尚未创建,则进入同步块。
  3. 第二次检查:在同步块内再次检查实例是否已经存在。这是为了防止多个线程同时通过第一次检查后都尝试创建实例。
  4. 创建实例:如果实例仍然为 null,则创建实例并赋值给静态变量。
代码示例

以下是完整的双重检查锁定模式实现单例的示例代码:

public class Singleton {// 使用 volatile 确保实例的可见性和防止指令重排序private static volatile Singleton instance;// 私有构造函数,防止外部实例化private Singleton() {// 防止反射攻击(可选)if (instance != null) {throw new RuntimeException("Use getInstance() method to get the single instance.");}}// 提供全局访问点public static Singleton getInstance() {// 第一次检查:避免不必要的同步if (instance == null) {synchronized (Singleton.class) {// 第二次检查:确保只有一个线程能创建实例if (instance == null) {instance = new Singleton();}}}return instance;}// 测试方法public void showMessage() {System.out.println("Hello from Singleton instance!");}public static void main(String[] args) {// 多线程测试Runnable task = () -> {Singleton singleton = Singleton.getInstance();singleton.showMessage();};Thread t1 = new Thread(task);Thread t2 = new Thread(task);t1.start();t2.start();}
}
代码解析
  1. volatile 关键字的作用

    • 确保 instance 的可见性:当一个线程修改了 instance 的值,其他线程能够立即看到最新的值。
    • 防止指令重排序:在 JVM 中,对象的创建可能被分解为以下步骤:
      1. 分配内存空间。
      2. 初始化对象。
      3. 将引用指向分配的内存地址。 如果没有 volatile,JVM 可能会因为指令重排序导致其他线程看到一个未完全初始化的对象。
  2. 双重检查的意义

    • 第一次检查:减少同步的开销。如果实例已经存在,直接返回,避免进入同步块。
    • 第二次检查:确保只有一个线程能够创建实例,即使多个线程同时通过了第一次检查。
  3. 私有构造函数

    • 防止外部通过 new Singleton() 创建新的实例。
    • 可以进一步增强安全性,防止反射攻击。
  4. 多线程测试

    • 通过两个线程同时调用 getInstance() 方法,验证是否只有一个实例被创建。
运行结果

运行上述代码时,输出结果类似如下(顺序可能不同):

Hello from Singleton instance!
Hello from Singleton instance!

尽管有两个线程同时调用 getInstance() 方法,但只会创建一个 Singleton 实例。

注意事项

  1. volatile 是必需的

    • 如果不使用 volatile,可能会因为指令重排序导致其他线程看到未完全初始化的对象,从而引发问题。
  2. 反射攻击

    • 即使使用了私有构造函数,仍然可以通过反射机制强制调用构造函数创建新的实例。可以在构造函数中添加检查逻辑来防止这种情况。
  3. 序列化问题

    • 如果单例类实现了 Serializable 接口,反序列化时可能会创建新的实例。可以通过定义 readResolve() 方法解决此问题:
      protected Object readResolve() {return instance;
      }

2. 显式锁 (Lock 接口)

工作原理
  • 显式调用:需要显式地调用 lock() 方法来获取锁,并在finally块中调用 unlock() 方法来释放锁。
  • 多种锁机制:提供了比 synchronized 更多的锁机制,如可重入锁、读写锁等。
特性
  • 灵活性高:可以通过编程控制何时锁定、解锁,允许尝试获取锁、定时获取锁等操作。
  • 可中断:可以中断正在等待获取锁的线程,避免了潜在的阻塞问题。例如,lockInterruptibly() 方法允许你中断正在等待获取锁的线程。
  • 公平性选择:可以选择是否启用公平锁(先请求的线程优先获得锁),有助于防止饥饿现象。例如,new ReentrantLock(true) 创建一个公平锁。
  • 多种条件变量:支持多个条件变量(Condition),比 synchronized 的单一条件通知机制更为灵活。例如,你可以使用 newCondition() 方法创建多个条件变量。
  • 支持重入:同样支持重入,即同一个线程可以多次获取同一个锁。这也是通过计数器机制实现的。
示例代码
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;public class LockExample {private final Lock lock = new ReentrantLock();private final Condition condition = lock.newCondition();private int count = 0;// 使用显式锁进行同步public void increment() {lock.lock(); // 获取锁try {count++;} finally {lock.unlock(); // 确保在finally块中释放锁,避免死锁}}// 条件变量的使用public void awaitAndSignal() throws InterruptedException {lock.lock();try {System.out.println("Before await");condition.await(); // 当前线程等待System.out.println("After await");} catch (InterruptedException e) {Thread.currentThread().interrupt(); // 重新设置中断标志} finally {lock.unlock();}lock.lock();try {condition.signal(); // 唤醒等待的线程} finally {lock.unlock();}}// 尝试获取锁并设置超时时间public void incrementWithTimeout() throws InterruptedException {if (lock.tryLock(1, TimeUnit.SECONDS)) { // 尝试获取锁,最多等待1秒try {count++;} finally {lock.unlock();}} else {System.out.println("Unable to acquire lock");}}// 可中断锁获取public void incrementInterruptibly() throws InterruptedException {lock.lockInterruptibly(); // 可以响应中断的锁获取try {count++;} finally {lock.unlock();}}// 使用公平锁public static void fairLockExample() {Lock fairLock = new ReentrantLock(true); // 创建一个公平锁// 使用fairLock进行同步操作}
}

实际应用中的最佳实践

  • 简单同步需求:如果你只需要对方法或代码块进行简单的同步处理,synchronized 是一个不错的选择,因为它简单且不易出错。
  • 复杂同步需求:如果你需要更多的控制,比如定时锁等待、可中断锁等待或公平锁等高级功能,那么 Lock 接口将是更好的选择。
  • 锁细化:尽量缩小同步区域范围,以减少线程之间的争用,提高并发效率。
  • 双重检查锁定:在单例模式中常用,减少同步开销。双重检查锁定是一种优化技术,用于延迟初始化单例对象,减少同步开销。
  • 使用显式锁:如 ReentrantLockReadWriteLock 提供了比 synchronized 更灵活的锁机制。特别是 ReadWriteLock 可以允许多个线程同时读取数据,但只允许一个线程写入数据。
  • 避免死锁:确保所有线程以相同的顺序获取锁,避免循环等待的情况发生。例如,定义一个全局的锁获取顺序,并严格遵守该顺序。

注意事项

  • 性能对比:虽然 synchronized 在很多情况下表现良好,但对于某些复杂的并发场景,显式锁(如 ReentrantLock)可能提供更好的性能和更大的灵活性。
  • 异常处理:在使用显式锁时,务必在finally块中释放锁,以防止因异常而导致死锁。
  • 调试技巧:利用日志或调试工具监控锁的状态和线程的行为,可以帮助诊断并发问题。

文章转载自:

http://8GhSUusC.knfgn.cn
http://LhmT5oYa.knfgn.cn
http://BrZNLmvy.knfgn.cn
http://msRKVCGT.knfgn.cn
http://zfCkFimi.knfgn.cn
http://mueOD498.knfgn.cn
http://FhULiTKD.knfgn.cn
http://XnL8G0N5.knfgn.cn
http://tVoS3i8S.knfgn.cn
http://l9qzwFEP.knfgn.cn
http://nkyKsLkz.knfgn.cn
http://mwYE1QBn.knfgn.cn
http://bip4nSfa.knfgn.cn
http://8k1gw4rX.knfgn.cn
http://39NKOfaU.knfgn.cn
http://2igTncng.knfgn.cn
http://6ABrLWLd.knfgn.cn
http://OAapjlga.knfgn.cn
http://uWDFFOrg.knfgn.cn
http://B1PYuhtU.knfgn.cn
http://mJD3nKX9.knfgn.cn
http://aI4SsgVM.knfgn.cn
http://t8dDuXg1.knfgn.cn
http://WyD5UAdG.knfgn.cn
http://bJxd6LwC.knfgn.cn
http://0iJEKhxt.knfgn.cn
http://JAXGYZHK.knfgn.cn
http://41EAtC54.knfgn.cn
http://uMTaH0Ba.knfgn.cn
http://r69PhS2H.knfgn.cn
http://www.dtcms.com/wzjs/722815.html

相关文章:

  • 动漫做a视频网站win10优化
  • 河东区腾讯网站建设华为云云速建站
  • 网站员工风采深圳建筑设计师招聘信息
  • dw做的网站怎么放到服务器上个人网站代码编写
  • 成立门户网站建设工作小组给教育类做网站
  • 大连 网站wordpress怎么引用新浪ajax
  • 个人建立网站后怎么盈利做家教网站
  • 平顶山做网站的公司搭建一个网站需要哪些技术
  • 建设网站费用分析国外媒体报道
  • 3d 代做网站个人网站二级域名做淘宝客
  • 杭州余杭网站建设南宁网页设计培训学校
  • 青岛专业网站建设定制免费图片制作生成器
  • 网站建设应解决的问题买购网
  • 太原推广型网站建设wordpress转换为html
  • 利用表单大师做网站深圳发布稳增长措施
  • 做水晶接单在哪个网站接简单班级网站模板
  • 手机网站免费模板下载郑州做网站哪家专业
  • 唐山网站制作服务公司wordpress更改站点地址
  • 教育网站建设公司网站500兆空间多少钱
  • 基层档案网站建设建设网站 (公司)
  • psd资源下载网站模板wordpress 意见反馈
  • 佛山制作网站公司吗做视频网站要多大的服务器
  • 免费网站制作模板百度网站怎么做视频播放器
  • 网站鼠标的各种效果怎么做的Wordpress要建数据库吗
  • 文化传媒建设网站免费代理服务器国外
  • 网站关键词筛选建筑工程公司起名
  • 北京专业网站外包公司龙华个人网站建设
  • 未来网站建设想法营销型手机网站
  • 网站开发视频教学腾讯会议30人以上收费
  • 做一网站要什么软件有哪些logo网站免费