0

下面是我的界面 -

public interface IClient {
    public String read(ClientInput input);
}

这是我的接口实现 -

public class TempClient implements IClient {

    @Override
    public String read(ClientInput input) {

    }
}

以下是我的工厂代码 -

public class TempClientFactory {

    public static IClient getInstance() {
    new TempScheduler().startScheduler();
    return ClientHolder.INSTANCE;
    }

    private static class ClientHolder {
        private static final TempClient INSTANCE = new TempClient();
    }
}

现在我有一个工厂,它像这样获取 TempClient 的实例,因此客户在调用我们的代码时将使用我们的工厂,如下所示。

IClient client = TempClientFactory.getInstance();
client.read(input);

下面是我的后台线程代码 -

public class TempScheduler {

    private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);

        public void startScheduler() {
            final ScheduledFuture<?> taskHandle = scheduler.scheduleAtFixedRate(new Runnable() {
                public void run() {
                try {
                    callServers();
                } catch (Exception ex) {
                    ex.printStackTrace();
                }
                }
            }, 0, 10L, TimeUnit.MINUTES);
        }
    }

    //... some code
}

问题陈述:-

  1. 现在我有一个后台线程,它将在后台运行,它从 URL 中获取数据,解析它并将其存储在一个变量中。现在我想要的是,一旦我们的客户开始使用工厂调用使用我们的代码,我希望后台线程启动。所以我决定把这个电话放在我上面TempClientFactory,它工作得很好..

现在这种方法的问题是,客户将继续调用我的 TempClientFactory 所以它会一直启动后台线程。我正在寻找的是,如果后台线程启动一次,那么我不想启动它再次从另一个线程开始,但它应该在幕后每 10 分钟运行一次,因为它已经第一次启动了。

如果我的理解是正确的,假设如果我调用我的 TempClientFactory 一次,那么它将启动后台线程,我的后台线程将继续每 10 分钟运行一次。如果我再次调用我的工厂,那么它将启动相同再次后台,它也将每 10 分钟运行一次?或者它只会启动一个每 10 分钟运行一次的后台线程?

4

2 回答 2

0

使用单例方法,这将确保您拥有一个类的单个实例。创建 TempScheduler 的对象只需调用

 public class TempClientFactory {

    public static IClient getInstance() 
   {

       TempScheduler  obj=TempScheduler.getTempScheduler(); 
       if(obj.flag==false) 
       {
        obj.startScheduler();
       }
       return ClientHolder.INSTANCE;
    }

    private static class ClientHolder {
        private static final TempClient INSTANCE = new TempClient();
    }
}






 public class TempScheduler {

            private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1);
            public static TempScheduler scheduler=null;
            public bool flag;

                public void startScheduler() {
                    flag=true;
                    final ScheduledFuture<?> taskHandle = scheduler.scheduleAtFixedRate(new Runnable() {
                        public void run() {
                        try {
                            callServers();
                        } catch (Exception ex) {
                            ex.printStackTrace();
                        }
                        }
                    }, 0, 10L, TimeUnit.MINUTES);
                }
            }

            private TempScheduler()
            {

            }

            synchronized public static TempScheduler getTempScheduler()
            {
             if(scheduler==null)
             {
                scheduler=new TempScheduler();
             }
             return scheduler;
           }


            //... some code
        }
于 2014-01-22T05:05:08.563 回答
0

您需要手动阻止它再次被调用。static您可以向内部类添加一个块。

public class TempClientFactory {
    public static IClient getInstance() {
        return ClientHolder.INSTANCE;
    }

    private static class ClientHolder {
        private static final TempClient INSTANCE = new TempClient();

        static {
            // You could do this here, as well, if it were more complicated
            //  than a one-line statement (e.g., requires try/catch):
            //INSTANCE = new TempClient();

            new TempScheduler().startScheduler();
        }
    }
}

与 JVM 为实例化单例所保证的线程安全、延迟加载类似,它也将保证一次性访问此处启动调度程序。

因此,您将只启动和安排您的线程运行一次。

另外,我建议将您转换ex.printStackTrace();为实际的日志语句。

于 2014-01-22T05:49:14.663 回答