0 0

多线程的一个疑惑5

如下代码:
public class A{
   private static final A instance = new A();
   
   public A getInstance() {
        return instance;
   }
   protect A(){
     ...
     ...
   }
}

当线程1调用getInstance函数,
线程1会new 这个instance 对象。当instance还没构造完,线程1挂起
此时线程2也调用getInstance函数,问题来了,此时线程2会不会从新构造这个对象?

问题补充:public A getInstance() { 
        return instance; 
   } 

应改成
public static  A getInstance() { 
        return instance; 
   } 

问题补充:刚刚google了一下,有个解释很好:
As per Java Language Specification, constructors cannot be synchronized because other threads cannot see the object being created before the thread creating it has finished it. There is no practical need of a Java Objects constructor to be synchronized, since it would lock the object being constructed, which is normally not available to other threads until all constructors of the object finish

我的理解就是构造方法是同步的。

问题补充:当线程A没有构造完对象,线程B会一直卡住直到线程A完成构造后释放掉锁
2013年1月06日 15:30

6个答案 按时间排序 按投票排序

1 0


 类初始化的时候是同步的,当初始化完成后就改成非同步了,因为static 块和static field 在初始化的时候就完成了,所以不存在竞态条件,上面的代码没问题.
 另外如果构造函数在构造过程中,在以下情况下是线性安全:
   1.如果没有对static field 写的操作
      2.this 指针没有发布出去
     
 因为构造过程中,始终在单独线程里完成,所以如果构造函数没出现以上情况,一般来说是线性安全.

 可以参与一下这个:

http://stackoverflow.com/questions/10530348/object-construction-is-atomic-or-not

2013年1月06日 22:25
0 0

类的静态变量在类加载器加载类的时候 已经初始化了 这个先于new的操作  而且只加载一次 不存在并发问题

所以 当你用A类的实例 去调用的时候 不存在并发问题  永远都会拿到那个

可以看看  单例设计模式中的饱汉模式 与 饿汉模式

2013年1月08日 10:54
0 0

静态变量 在类初始化的时候就创建了 而且只创造一次 这个不存在并发问题 虚拟机会处理 因为类加载器对每个class只加载一次
而当你调用 A实例的方法的时候 静态变量已经初始化完毕了

2013年1月08日 10:51
0 0

Double-check Lock模式最好不要用在Singleton pattern中

2013年1月07日 16:56
0 0

看你写的是单例的样子,但好像还不是很完全。可以参考这个:

class Demo {
  private static Demo instance;

  private Demo () {
    if (instance != null)
      throw new RuntimeException("不能使用");
  }

  public static Demo getInstance () {
    if (instance == null) {
      instance = new Demo();
    }
    return instance;
  }
}

有几点要注意:
1.必须private 构造方法,使外界不能直接new出来。
2.构造中抛出exception,是防止使用反射进行实例化。
但这个例子只能作为个玩具,因为在以下2个情况都会有问题:
1.序列化
2.多线程

1.进行反序列化的时候,就会生成第二个实例,而破坏了单例的场景。
解决方法:
1.将实例字段用transit进行修饰。
2.增加readReslove()方法,如下:
public Object readReslove() {
  return instance;
}

2.在多线程场景下,如果在还没有实例化的时候,有多个并发请求getInstance()有可以造成多实例的情况。这时应该使用 双检查锁 机制:
public static Demo getInstance () {
  if (instance == null){
    synchronized(Demo.class) {
      if (instance == null){

        instance = new Demo();
      }
    }
 }
  return instance;
}

2013年1月06日 22:23
0 0

这个是单例模式的写法.
private static final A instance = new A();   这句代码应该是在类加载的时候都初始化了,类加载的时候就创建了对象(就是非延迟初始化).所以后续无论你有多少个线程,无论怎么阻塞,怎么挂起,都是不会再重新构造对象的.

2013年1月06日 16:39

相关推荐

    java多线程与并发库高级处理.txt

    用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现。说这个话其实只有一半对,因为反应“多角色”的程序代码,最起码每个角色要给他一个线程吧,否则连实际场景都无法...

    Java 线程间数据交换的疑惑

    在Java编程中,线程间的数据交换是一个关键的议题,特别是在多线程环境中。这篇博客“Java线程间数据交换的疑惑”可能探讨了在并发编程中如何有效地共享和同步数据。`volatile`关键字是Java中用于实现线程间通信的一...

    AS/400-多线程编程技术.pdf

    多线程编程的一个重要特性是在同一JOB内可以创建多个线程,这些线程共享JOB的资源,但每个线程也有其独立的执行环境。 ###### 1.3.4 线程的私有数据和共有数据 - **私有数据**:每个线程独有的数据,不会被其他...

    《多线程编程技术》

    多线程之间的通信是多线程编程的一个核心问题。常见的通信机制包括信号量、互斥锁和条件变量等。 ##### 1.7 线程的数据库、数据相关处理 多线程环境下数据库操作和数据处理需要特别注意线程安全性和数据一致性。 ...

    多线程编程技术《Programming Multithreaded applications

    线程安全性是多线程编程中一个非常重要的方面,需要确保程序在多线程环境下稳定运行。 ##### 存储用法和线程应用 存储用法决定了数据结构如何被多线程程序访问和修改,合理的存储用法有助于提高程序的线程安全性。 ...

    为什么多线程容易崩溃呢,我来揭秘下,测试线程运行崩溃例子 -易语言

    献给有需要的人,喜欢的支持下!! 为什么多线程容易崩溃呢,我来揭秘下,测试线程运行崩溃例子 之前写多线程一直疑惑为何突然就崩溃了,一直找不到原因,经过多番测试,终于找到问题所在了。。。给新手一个提示!!

    java多线程学习笔记02(csdn)————程序.pdf

    Java多线程编程是开发高并发应用的关键技术之一。在这个学习笔记中,主要讨论了Java中的线程同步机制,包括volatile关键字、synchronized以及Lock接口,特别是ReentrantLock的使用。 首先,对于线程1和线程2的疑惑...

    Java中的多线程你只要看这一篇就够了

    用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现。说这个话其实只有一半对,因为反应“多角色”的程序代码,最起码每个角色要给他一个线程吧,否则连实际场景都无法...

    来自IBM的(POSIX).

    ### 多线程编程在Linux环境下的特殊性和挑战 #### 概述 本文档旨在深入探讨多线程编程在Linux环境中的应用与挑战,主要内容基于IBM信息中心的《Programming Multithreaded applications》一书,并结合作者个人见解...

    关于CoreJava同步的疑惑例子

    在Java编程语言中,"同步"是一个至关重要的概念,特别是在多线程环境下。它涉及到如何控制并发执行的多个线程,以确保数据的一致性和完整性。在这个“关于CoreJava同步的疑惑例子”中,我们将探讨Java中的同步机制,...

    Thread线程的基础知识及常见疑惑点总结

    了解Thread类的基本概念和方法对于理解和使用Java多线程至关重要,这不仅有助于编写高效的并发程序,也有助于解决可能出现的并发问题。同时,熟悉这些基础知识也能更好地运用线程池和多线程框架,如ExecutorService...

    think in java 4 练习题答案

    继承允许一个类(子类)继承另一个类(父类)的特性,多态则是指同一种行为可以有不同的表现形式,是面向对象的重要特性。 4. **异常处理**:Java通过try-catch-finally语句块进行异常处理,使得程序在遇到错误时能...

    解决java中的疑惑

    3. **多线程编程**:Java提供了丰富的多线程支持。线程同步(synchronized关键字)、wait/notify机制、线程池(ExecutorService)以及并发集合类(如ConcurrentHashMap)都是学习的重点。 4. **面向对象编程**:...

    android中listview,gridview加载图片的线程并发解决方案

    (listview和gridview,viewpager同一个道理,大家举一反三)。这里涉及到三个知识点:1、通过网络下载图片资源。2、异步任务显示在UI线程上。3、解决当用户随意滑动的时候解决多线程并发的问题(这个问题是本教程要...

    详细分析单线程JS执行问题

    多线程会带来复杂的问题,例如在DOM操作中可能出现的一个线程读取DOM节点数据的同时,另一个线程却删除了该节点,这会导致麻烦和难以追踪的错误。 单线程的JavaScript在执行时只能一步一步顺序执行。如果遇到阻塞,...

Global site tag (gtag.js) - Google Analytics