ஒரு எளிய திட்டத்தைக் கவனியுங்கள்:


public static void main(String[] args) throws Exception {
	// Create an ExecutorService with a fixed number of threads: three
	ExecutorService service = Executors.newFixedThreadPool(3);
 
	// Pass a simple Runnable task to the ExecutorService
	service.submit(() -> System.out.println("done"));
}

நிரலை இயக்குவது நாம் எதிர்பார்க்கும் கன்சோல் வெளியீட்டை உருவாக்குகிறது:

முடிந்தது

ஆனால் IntelliJ IDEA இல் நாம் வழக்கமாகப் பார்க்கும் வெளியீடு இதைத் தொடர்ந்து இல்லை:

வெளியேறும் குறியீடு 0 உடன் செயல்முறை முடிந்தது

ஒரு ப்ரோக்ராம் முடிவடையும் போது அதை நாம் வழக்கமாகப் பார்க்கிறோம்.

அது ஏன் நடக்கிறது?

ஒரு ExecutorService ஐப் பயன்படுத்தி உருவாக்கப்பட்ட நூல்கள் வெளிப்படையாக நிறுத்தப்படும் வரை தொடர்ந்து இருக்கும் என்று newFixedThreadPool() முறையின் விளக்கம் கூறுகிறது . அதாவது, நாங்கள் ஒரு பணியை ExecutorService க்கு அனுப்பியதால் , அதைச் செயல்படுத்த ஒரு நூல் உருவாக்கப்பட்டது, மேலும் பணி முடிந்த பிறகும் அந்த நூல் தொடர்ந்து இருக்கும்.

ExecutorService இல் நிறுத்தப்படுகிறது

இதன் விளைவாக, நாம் ExecutorService ஐ "மூடு" (அல்லது நிறுத்த) வேண்டும் . இதை நாம் இரண்டு வழிகளில் செய்யலாம்:

  1. void shutdown() — இந்த முறை அழைக்கப்பட்ட பிறகு, ExecutorService புதிய வேலைகளை ஏற்றுக்கொள்வதை நிறுத்துகிறது. ExecutorService க்கு முன்னர் சமர்ப்பிக்கப்பட்ட அனைத்து பணிகளும் தொடர்ந்து இயங்கும்.

    
    public static void main(String[] args) throws Exception {
    ExecutorService service = Executors.newFixedThreadPool(3);
        	service.submit(() -> System.out.println("task 1"));
        	service.submit(() -> System.out.println("task 2"));
        	service.shutdown();
        	// A RejectedExecutionException will occur here
        	service.submit(() -> System.out.println("task 3"));
    }
    
  2. List<Runnable> shutdownNow() — இந்த முறை தற்போது செயலில் உள்ள வேலைகளை நிறுத்த முயற்சிக்கிறது. இன்னும் தங்கள் முறைக்காகக் காத்திருக்கும் பணிகள் நிராகரிக்கப்பட்டு, இயங்கக்கூடியவைகளின் பட்டியலாகத் திரும்பும் .

    
    public static void main(String[] args) throws Exception {
        ExecutorService service = Executors.newFixedThreadPool(5);
        List.of(1, 2, 3, 4, 5, 6, 7, 8).forEach(i -> service.submit(() -> System.out.println(i)));
        List<Runnable> runnables = service.shutdownNow();
        runnables.forEach(System.out::println);
    }
    

வெளியீடு:

1
2
4
3
java.util.concurrent.FutureTask@1e80bfe8[முடிவடையவில்லை, பணி = java.util.concurrent.Executors$RunnableAdapter@4edde6e5[Wrapped task = Test$Lambda$16/0x000000070700000000
தற்போதைய .FutureTask@cc34f4d[முடியவில்லை, டாஸ்க் = java.util.concurrent.Executors$RunnableAdapter@66a29884[Wrapped task = Test$$Lambda$16/0x0000000800b95040@479b]urf 9caf[
முடியவில்லை, பணி = java.util.concurrent.Executors$RunnableAdapter@17a7cec2[Wrapped task = Test$$Lambda$16/0x0000000800b95040@65b3120a]]
5

வெளியேறும் குறியீடு 0 உடன் செயல்முறை முடிந்தது

ரன் இருந்து ரன் வெளியீடு வேறுபடும். வெளியீட்டில் 2 வகையான வரிகள் உள்ளன:

  • ஒரு எண் என்பது, எக்ஸிகியூட்டர் சர்வீஸ் தொடர்புடைய பணியைச் செயல்படுத்தி, நாங்கள் பணிகளை உருவாக்கப் பயன்படுத்திய பட்டியலிலிருந்து எண்ணைக் காண்பிக்கும்.

  • FutureTask பொருளில் toString() முறையை அழைப்பதன் முடிவுகள் . இந்த ஆப்ஜெக்ட்கள் எக்ஸிகியூட்டர் சர்வீஸில் சமர்ப்பிக்கப்பட்ட ஆனால் செயலாக்கப்படாத பணிகள்.

வெளியீடு மற்றொரு சுவாரஸ்யமான நுணுக்கத்தைக் கொண்டுள்ளது. ஒரு சிறந்த உலகில், முதலில் காட்டப்படும் அனைத்து எண்களையும், அதைத் தொடர்ந்து FutureTask பொருட்களையும் பார்ப்போம் . ஆனால் ஒத்திசைவு சிக்கல்கள் வெளியீட்டில் உள்ள வரிகளை குழப்புகின்றன.

மற்ற முறைகள்

ExecutorService அதை நிறுத்துவது தொடர்பான இன்னும் பல முறைகளைக் கொண்டுள்ளது:

  1. boolean waiitTermination(நீண்ட நேரம் முடிந்தது, TimeUnit அலகு) - இந்த முறை அதை அழைக்கும் நூலைத் தடுக்கிறது. பின்வரும் மூன்று நிகழ்வுகளில் ஏதேனும் ஒன்று நிகழும் போதே தடை முடிவடைகிறது:

    • பணிநிறுத்தம்() முறை அழைக்கப்பட்ட பிறகு , அனைத்து செயலில் உள்ள வேலைகள் மற்றும் அனைத்து திட்டமிடப்பட்ட பணிகளும் செயல்படுத்தப்பட்டன;
    • முறை அளவுருக்களால் நிர்ணயிக்கப்பட்ட காலக்கெடு கடந்துவிட்டது;
    • awaitTermination() முறை என்று அழைக்கப்படும் நூல் நிறுத்தப்பட்டது.

    காலக்கெடு முடிவதற்குள் ExecutorService நிறுத்தப்பட்டால் இந்த முறை சரி என்றும், காலக்கெடு முடிந்துவிட்டால் தவறு என்றும் திரும்பும் .

    
    public static void main(String[] args) throws Exception {
    	ExecutorService service = Executors.newFixedThreadPool(2);
    	service.submit(() -> System.out.println("task 1"));
    	service.submit(() -> System.out.println("task 2"));
    	service.submit(() -> System.out.println("task 3"));
    	service.shutdown();
    	System.out.println(service.awaitTermination(1, TimeUnit.MICROSECONDS));
    }
    
  2. boolean isShutdown()ExecutorService இல் பணிநிறுத்தம் () அல்லது shutdownNow() முறை அழைக்கப்பட்டிருந்தால் உண்மை எனத் திரும்பும் .

    
    public static void main(String[] args) throws Exception {
    	ExecutorService service = Executors.newFixedThreadPool(2);
    	service.submit(() -> System.out.println("task 1"));
    	service.submit(() -> System.out.println("task 2"));
    	service.submit(() -> System.out.println("task 3"));
    	System.out.println(service.isShutdown());
    	service.shutdown();
    	System.out.println(service.isShutdown());
    }
    
  3. boolean isTerminated()ExecutorService இல் பணிநிறுத்தம் () அல்லது shutdownNow() முறை அழைக்கப்பட்டு , அனைத்து பணிகளும் முடிந்தால் உண்மை எனத் திரும்பும்.

    
    public static void main(String[] args) throws Exception {
        ExecutorService service = Executors.newFixedThreadPool(5);
        List.of(1, 2, 3, 4, 5, 6, 7, 8).forEach(i -> service.submit(() -> System.out.println(i)));
        service.shutdownNow();
        System.out.println(service.isTerminated());
    }
    

இந்த முறைகளைப் பயன்படுத்தும் எடுத்துக்காட்டு குறியீடு:


public static void main(String[] args) throws Exception {
   ExecutorService service = Executors.newFixedThreadPool(16);
   Callable<String> task = () -> {
       Thread.sleep(1);
       return "Done";
   };
 
   // Add 10,000 tasks to the queue
   List<Future<String>> futures = IntStream.range(0, 10_000)
           .mapToObj(i -> service.submit(task))
           .collect(Collectors.toList());
   System.out.printf("%d tasks were submitted for execution.%n", futures.size());
 
   // Attempt to shut down
   service.shutdown();
   // Wait 100 milliseconds to finish the work
   if (service.awaitTermination(100, TimeUnit.MILLISECONDS)) {
       System.out.println("All tasks completed!");
   } else {
       // Stop forcibly
       List<Runnable> notExecuted = service.shutdownNow();
       System.out.printf("%d tasks were not started.%n", notExecuted.size());
   }
 
   System.out.printf("Total tasks completed: %d.%n", futures.stream().filter(Future::isDone).count());
}

வெளியீடு (ஓட்டத்திலிருந்து இயக்கத்திற்கு மாறுபடும்):

10,000 பணிகள் நிறைவேற்றுவதற்காக சமர்ப்பிக்கப்பட்டன.
9170 பணிகள் தொடங்கப்படவில்லை.
முடிக்கப்பட்ட மொத்த பணிகள்: 830 பணிகள்.

வெளியேறும் குறியீடு 0 உடன் செயல்முறை முடிந்தது