创建新对象后控制方法调用的调用

我有一个预定的方法调用,它在预定的时间调用以下方法:


private void doSomething(Map<String, String> someArguments) throws CustomException {

  MyEnum runType = getRunType(someArguments);

  switch (runType) {

        case FRUIT:

             new FruitClass().workNow();

             break;


        case VEGETABLE:

             new VegetableClass().workNow();

             break;


        default:

            // log that the type is not known 

      }

   }

的方法签名workNow是这样的:


workNow() throws CustomException

workNow方法运行几分钟并做一些工作。我的问题是,当一个workNowfor FRUIT(or VEGETABLE) 正在进行并且另一个调用发生在相同类型(FRUIT例如)时,它会创建一个新FruitClass实例并开始workNow并行执行它。


我如何控制这种行为?我希望通过第二个对象的第二次调用等到第一个workNow到第一个对象未完成。


澄清:


并行调用FRUIT和VEGETABLE很好。我想控制相同类型的并行调用。两个以上FRUIT或两个以上VEGETABLE。


我不能FruitClass和VegetableClass单身人士一样。我需要一些包装代码来new按照我想要的方式工作。


LEATH
浏览 187回答 3
3回答

PIPIONE

几个解决方案,我能想到:解决方案1static final String FRUIT = "FRUIT";static final String VEGETABLE = "VEGETABLE";private void doSomething(Map<String, String> someArguments) {&nbsp; &nbsp; MyEnum runType = getRunType(someArguments);&nbsp; &nbsp; &nbsp; &nbsp; switch (runType) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case FRUIT:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; synchronized (FRUIT){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new FruitClass().workNow();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case VEGETABLE:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; synchronized (VEGETABLE){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new VegetableClass().workNow();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // log that the type is not known&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }}这可能比使用class对象更好,因为它们会更重并消耗内存。解决方案2这是对解决方案 1 的增强,以防有多个案例并且String不需要类级别。private void doSomething(Map<String, String> someArguments) {&nbsp; &nbsp; MyEnum runType = getRunType(someArguments);&nbsp; &nbsp; synchronized(runType.toString().intern()) {//This prevents 2 FRUITs or 2 VEGETABLEs from entering&nbsp; &nbsp; &nbsp; &nbsp; switch (runType) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case FRUIT:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new FruitClass().workNow();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; case VEGETABLE:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new VegetableClass().workNow();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // log that the type is not known&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}两者都在一个略有不同的示例中进行了测试,但要说明这一点。

潇湘沐

肯定有很多方法可以解决这个问题。我认为最简单的方法是为每种类型的任务使用单线程池://one pool per runTypeprivate final ExecutorService fruitService = Executors.newSingleThreadExecutor();private final ExecutorService vegService = Executors.newSingleThreadExecutor();进而:private void doSomething(Map<String, String> someArguments) {&nbsp; &nbsp; MyEnum runType = getRunType(someArguments);&nbsp; &nbsp; CompletableFuture<Void> result;&nbsp; &nbsp; switch (runType) {&nbsp; &nbsp; case FRUIT:&nbsp; &nbsp; &nbsp; &nbsp; result = CompletableFuture.runAsync(() ->&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new FruitClass().workNow(), fruitService)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .exceptionally((exception) -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (exception instanceof CustomException) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Failed with custom exception...");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null; // returning Void&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; case VEGETABLE:&nbsp; &nbsp; &nbsp; &nbsp; result = CompletableFuture.runAsync(() ->&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new VegetableClass().workNow(), vegService)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .exceptionally((exception) -> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (exception instanceof CustomException) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; System.out.println("Failed with custom exception...");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return null; // returning Void&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; });&nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; throw new RuntimeException();&nbsp; &nbsp; }&nbsp; &nbsp; result.join();}这只是强制并发调用等待资源,并且不会同时运行 2 个相同类型的任务。它提供了异步执行的额外好处,尽管您可以在需要时显式阻塞以等待结果。

慕标5832272

在类对象上进行同步,这足以避免在完成之前创建另一个类:private void doSomething(Map<String, String> someArguments) {&nbsp; &nbsp; MyEnum runType = getRunType(someArguments);&nbsp; &nbsp; switch (runType) {&nbsp; &nbsp; &nbsp; &nbsp; case FRUIT:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; synchronized (FruitClass.class){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new FruitClass().workNow();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; case VEGETABLE:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; synchronized (VegetableClass.class){&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new VegetableClass().workNow();&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;&nbsp; &nbsp; &nbsp; &nbsp; default:&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; // log that the type is not known&nbsp;&nbsp; &nbsp; }}synchronized在类对象上使用类实例作为监视器。类对象实际上是一个单例(在运行时代表类元数据的对象),并且这个块中只能有一个线程。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Java