使用线程,我有一个主要类(SlaveCrawler
),它实例化三个类(Downloader, ContentAnalyzer, URLAnalyzer
),它们相互依赖。
SlaveCrawler
使用Downloader
和URLAnalyzer
Downloader
使用ContentAnalyzer
和URLAnalyzer
ContentAnalyzer
使用URLAnalyzer
我只想要每个类的一个实例。如果我使用Singleton
,我可以得到这个,但是使用线程,我将有20 SlaveCrawlers
(示例),所以我想要20 URLAnalyzer
。
有可能使用Singleton
或我需要其他方式吗?
答案 0 :(得分:21)
看看ThreadLocal。每个线程都有自己的每个对象的本地副本。
ThreadLocal<YourObject> threadLocalYourObject = new ThreadLocal<YourObject>() {
@Override
protected YourObject initialValue() {
//initialize YourObject
}
}
或者在1.8中我们可以使用:
ThreadLocal<YourObject> threadLocalYourObject = ThreadLocal.withInitial( () -> new YourObject() )
要访问ThreadLocal对象,请使用get()方法。
YourObject yourObject = threadLocalYourObject.get();
答案 1 :(得分:4)
您可以使用ThreadLocal实现它。 这是伪代码:
public class ThreadLocalTest {
public static void main(String[] args){
MyTLSingleTon obj = MyTLSingleTon.getInstance();
}
}
class MyTLSingleTon{
private MyTLSingleTon(){
}
private static final ThreadLocal<MyTLSingleTon> _localStorage = new ThreadLocal<MyTLSingleTon>(){
protected MyTLSingleTon initialValue() {
return new MyTLSingleTon();
}
};
public static MyTLSingleTon getInstance(){
return _localStorage.get();
}
}
MyTLSingleTon.getInstance();
方法将返回与当前线程相关的对象。如果没有关联对象,则调用protected MyTLSingleTon initialValue()
方法并设置新实例。
答案 2 :(得分:2)
是。这是可能的。
在/“返回单例”的方法中(例如getInstance()),使用线程局部存储来检查(并在需要时创建)要返回的单例对象的实例。
然而,这个听起来很混乱。考虑到不使用“单一模式”;而是根据需要传递相同的对象(或考虑使用DI框架)。
快乐的编码。
答案 3 :(得分:-1)
I have used the implementation as explained above, I am able to achieve the single object per thread.
Below is my complete implementation
package example.test;
public class ThreadLevelSingleton
{
public static void main(String[] args)
{
Thread33 t3 = new Thread33();
t3.run();
Thread44 t4 = new Thread44();
t4.run();
MySingleTon m1 = MySingleTon.getInstance();
MySingleTon m2 = MySingleTon.getInstance();
System.out.println(Thread.currentThread().getName() + " : " + (m1 == m2));
MySingleTon tm1 = t3.getMySingleTon();
MySingleTon tm2 = t4.getMySingleTon();
System.out.println(Thread.currentThread().getName() + " : " + (tm1.equals(tm2)));
}
}
class MySingleTon
{
private MySingleTon()
{
}
private static final ThreadLocal<MySingleTon> t = new ThreadLocal<MySingleTon>()
{
@Override
protected MySingleTon initialValue()
{
return new MySingleTon();
}
};
public static MySingleTon getInstance()
{
return t.get();
}
}
class Thread33 extends Thread
{
MySingleTon m1;
@Override
public void run()
{
MySingleTon t = MySingleTon.getInstance();
MySingleTon t1 = MySingleTon.getInstance();
m1 = MySingleTon.getInstance();
System.out.println(getName() + " : " + (t == t1));
System.out.println(t);
System.out.println(t1);
}
MySingleTon getMySingleTon()
{
return m1;
}
}
class Thread44 extends Thread
{
MySingleTon m1;
@Override
public void run()
{
MySingleTon t = MySingleTon.getInstance();
MySingleTon t1 = MySingleTon.getInstance();
m1 = MySingleTon.getInstance();
System.out.println(getName() + " : " + (t == t1));
System.out.println(t);
System.out.println(t1);
}
MySingleTon getMySingleTon()
{
return m1;
}
}