Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 带单例的ThreadLocal_Java_Multithreading - Fatal编程技术网

Java 带单例的ThreadLocal

Java 带单例的ThreadLocal,java,multithreading,Java,Multithreading,我正在编写以下代码。两个线程需要它们自己的单实例。线程本地是一个明显的解决方案。但是,我仍然面临使用自己的本地副本运行线程的问题。我在几个java类中有一个场景示例 public class Singleton1 { private int i = 0; private static Singleton1 instance; private Singleton1() { } public static final Singleton1 getInstance() { if (in

我正在编写以下代码。两个线程需要它们自己的单实例。线程本地是一个明显的解决方案。但是,我仍然面临使用自己的本地副本运行线程的问题。我在几个java类中有一个场景示例

public class Singleton1 {

private int i = 0;

private static Singleton1 instance;

private Singleton1() {
}

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

public int increment() {
    return i++;
}

}

public class Holder1 {

private final Singleton1 instance;

public Holder1() {
    ThreadLocalSingleton1 singleton1 = new ThreadLocalSingleton1();
    instance = singleton1.get();
}

public int increment() {
    return instance.increment();
}

private class ThreadLocalSingleton1 extends ThreadLocal<Singleton1> {

    @Override
    protected Singleton1 initialValue() {
        return Singleton1.getInstance();
    }

}

}

public class HolderTest {

/**
 * @param args
 */
public static void main(String[] args) {
    HolderTest test = new HolderTest();
    HolderThread thread1 = test.getHolderThread("thread1");
    HolderThread thread2 = test.getHolderThread("thread2");
    thread1.run();
    thread2.run();

}

public HolderThread getHolderThread(String name) {
    return new HolderThread(name);
}

private class HolderThread implements Runnable {
    String name;

    Holder1 holder1 = new Holder1();

    public HolderThread(String name) {
        this.name = name;
    }

    @Override
    public void run() {
        while (true) {
            System.out.println(name + " " + holder1.increment());
        }
    }
}
公共类单音1{
私有整数i=0;
私有静态单例1实例;
私人单音1(){
}
公共静态最终Singleton1 getInstance(){
if(实例==null){
instance=newsingleton1();
}
返回实例;
}
公共整数增量(){
返回i++;
}
}
公共类持有者1{
私人最终单音1例;
公众持股人1(){
ThreadLocalSingleton1 singleton1=新的ThreadLocalSingleton1();
instance=singleton1.get();
}
公共整数增量(){
返回instance.increment();
}
私有类ThreadLocalSingleton1扩展了ThreadLocal{
@凌驾
受保护的Singleton1初始值(){
返回Singleton1.getInstance();
}
}
}
公共类持有者测试{
/**
*@param args
*/
公共静态void main(字符串[]args){
HolderTest测试=新的HolderTest();
HolderThread thread1=test.getHolderThread(“thread1”);
HolderThread thread2=test.getHolderThread(“thread2”);
thread1.run();
thread2.run();
}
public HolderThread getHolderThread(字符串名称){
返回新的HolderThread(名称);
}
私有类HolderThread实现Runnable{
字符串名;
Holder1 Holder1=新的Holder1();
公共保持线程(字符串名称){
this.name=名称;
}
@凌驾
公开募捐{
while(true){
System.out.println(name+“”+holder1.increment());
}
}
}
当ThreadLocalWrappers在Singleton类上调用getInstance时,我不会每次都得到一个新的实例?我如何才能使这项工作符合我的目的

上面的代码是我正在使用的实际代码的一个简单版本。我有单例类,不能将其从单例更改为单例。我正在创建一个测试客户端,该客户端需要作为单个进程运行,但有多个线程。这些线程中的每一个都需要有自己的单例。

对多线程使用同步ng

public static synchronized final Singleton getInstance() {
这样,线程将“锁定”该方法:一次只允许一个线程进入该方法,其他线程将阻止该方法,直到该方法被解锁(执行该方法的线程离开)。您将不会遇到这些并发问题

此外,您不需要2个单例(这实际上是毫无意义的,并且违背了单例本身的目的……。

使用synchronized进行多线程处理

public static synchronized final Singleton getInstance() {
这样,线程将“锁定”该方法:一次只允许一个线程进入该方法,其他线程将阻止该方法,直到该方法被解锁(执行该方法的线程离开)。您将不会遇到这些并发问题


另外,您不需要2个单例(这实际上毫无意义,并且违背了单例本身的目的……。

您的目标类不应该是单例,但您必须仅使用ThreadLocal访问它,如果ThreadLocal实例为空(不包含对目标对象实例的引用),则创建一个新实例


另一种解决方案是将目标类设置为singleton,并将其状态保存在ThreadLocal变量中。

目标类不应为singleton,但必须使用ThreadLocal来访问它,如果ThreadLocal实例为空(不保存对目标对象实例的引用),则创建一个新实例


另一个解决方案是将目标类设置为singleton,并将其状态保存在ThreadLocal变量中。

您的意思是这样的吗

private static final ThreadLocal<AtomicInteger> COUNTER = new ThreadLocal<AtomicInteger>() {
    @Override
    protected AtomicInteger initialValue() {
        return new AtomicInteger();
    }
};

public static int incrementAndGet() {
    return COUNTER.get().incrementAndGet();
}
private static final ThreadLocal COUNTER=new ThreadLocal(){
@凌驾
受保护的AtomicInteger初始值(){
返回新的AtomicInteger();
}
};
public static int incrementAndGet(){
返回计数器.get().incrementAndGet();
}

你的意思是这样的吗

private static final ThreadLocal<AtomicInteger> COUNTER = new ThreadLocal<AtomicInteger>() {
    @Override
    protected AtomicInteger initialValue() {
        return new AtomicInteger();
    }
};

public static int incrementAndGet() {
    return COUNTER.get().incrementAndGet();
}
private static final ThreadLocal COUNTER=new ThreadLocal(){
@凌驾
受保护的AtomicInteger初始值(){
返回新的AtomicInteger();
}
};
public static int incrementAndGet(){
返回计数器.get().incrementAndGet();
}

请看下面的
ThreadLocal
工作示例:

public class YourDataHolder {
    private static ThreadLocal dataVariable = new ThreadLocal();
    private static YourDataHolder dataHolderVar;
    private YourDataHolder() { }
    public void storeDataToThreadLocal (String userName) {
        dataVariable.set(userName);
    }
    public String readDataFromThreadLocal ()  {
        if (dataVariable.get() != null) {
            return (String) dataVariable.get();
        }
    }
    public static ServiceVersionHolder getInstance () {
        if (dataHolderVar == null) {
         dataHolderVar = new YourDataHolder();
        }
        return dataHolderVar;
    }
}

请看下面的
ThreadLocal
工作示例:

public class YourDataHolder {
    private static ThreadLocal dataVariable = new ThreadLocal();
    private static YourDataHolder dataHolderVar;
    private YourDataHolder() { }
    public void storeDataToThreadLocal (String userName) {
        dataVariable.set(userName);
    }
    public String readDataFromThreadLocal ()  {
        if (dataVariable.get() != null) {
            return (String) dataVariable.get();
        }
    }
    public static ServiceVersionHolder getInstance () {
        if (dataHolderVar == null) {
         dataHolderVar = new YourDataHolder();
        }
        return dataHolderVar;
    }
}

你好像被画进了一个角落

一方面,您需要测试现有的代码库,并且代码使用(真正的、正确实现的)单例对象。特别是,在示例类
Singleton1
中将
Singleton1()
构造函数声明为
private
,使得无法声明子类

另一方面,您的测试要求您编写一个包含大量此类
Singleton1
实例的客户机

从表面上看,这是不可能的。无法在JVM中创建两个
Singleton1
类的实例,也无法声明
Singleton1
的(可编译/可加载)子类

这是每个设计;也就是说,它是
Singleton1
类的设计者想要的。(如果不是,那么答案是更改
Singleton1
以使其更易于测试。例如,通过使
Singleton1
构造函数不
私有
,以便可以为测试目的创建多个实例。)

(例如,当前实现
ThreadLocalSingleton1
的尝试失败,因为
Singleton1.getInstance()
返回
Singleton1
的全局实例。无论您做什么,都无法创建
Singleton1
类的任何其他实例。)

然而,我可以为您的特定用例想出两种变通方法

我正在编写一个需要