2010-05-24 15 views
7

मैंने जावा स्विंग एप्लिकेशन विकसित किया है, जो कुछ लंबे समय तक चलने वाले कार्यों को करने के लिए स्विंगवर्कर वर्ग का उपयोग करता है। जब एप्लिकेशन आईडीई (नेटबीन्स) से चलाया जाता है, तो मैं बिना किसी समस्या के एक साथ कई लंबे समय तक चलने वाले कार्यों को शुरू कर सकता हूं।रननेबल जार फ़ाइल के साथ निष्पादित करते समय जावा थ्रेड को एकाधिक थ्रेड के साथ कैसे हल करें?

मैंने आईडीई के बाहर से इसे चलाने में सक्षम होने के लिए, एप्लिकेशन के लिए एक चलने योग्य जार फ़ाइल बनाई है। इस जार फ़ाइल से चलने वाला एप्लिकेशन केवल अपवाद के साथ काम करता है कि यह मुझे एक साथ 2 लंबे समय तक चलने वाले कार्यों को शुरू करने की अनुमति नहीं देता है। कार्य सिर्फ दूसरे के बाद एक चलाते हैं।

मैं एक बहुत ही सरल प्रोग्राम बनाने में कामयाब रहा जो इस समस्या को प्रदर्शित करता है। link प्रोग्राम एक स्विंगवर्कर का उपयोग करता है जो केवल 1 से 100 तक लूप करता है और कंसोल को नंबर लिखता है। दो बटन दो थ्रेड शुरू करते हैं जो एक ही काम करते हैं। यदि मैं नेटबीन्स पर इस प्रोग्राम को चलाता हूं, तो थ्रेड इंटरलीव करते हैं, जबकि अगर मैं एक जार फ़ाइल बनाता हूं और जार फ़ाइल से एप्लिकेशन चलाता हूं, तो थ्रेड इंटरलीव नहीं करते हैं, लेकिन एक के बाद एक चलाते हैं।

ऐसा लगता है जैसे jvm किसी भी समय एक से अधिक थ्रेड चलाने की अनुमति नहीं देता है, जब एप्लिकेशन जार फ़ाइल से चलाया जाता है।

यहाँ आप लिंक के साथ समस्या हो

package testingjarpath; 

import java.awt.Dimension; 
import java.awt.FlowLayout; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.util.List; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.SwingUtilities; 
import javax.swing.SwingWorker; 

public class Main extends JFrame { 
    private JButton btnTest; 
    private JButton btnTest2; 

    public Main() { 

     this.btnTest = new JButton("Test 1"); 
     this.btnTest.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       new Main.MyTask("First").execute(); 
      } 
     }); 

     this.btnTest2 = new JButton("Test 2"); 
     this.btnTest2.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       new Main.MyTask("Second").execute(); 
      } 
     }); 

     this.setLayout(new FlowLayout()); 
     this.add(this.btnTest); 
     this.add(this.btnTest2); 
     this.setSize(new Dimension(400, 400)); 
     this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     this.setVisible(true); 
    } 

    public static void main(String[] args) { 
     SwingUtilities.invokeLater(new Runnable() { 
      public void run() { 
       new Main(); 
      } 
     }); 
    } 

    public class MyTask extends SwingWorker<Void, Integer> { 
     private String str; 

     public MyTask(String str) { 
      this.str = str; 
     } 

     @Override 
     protected Void doInBackground() throws Exception { 
      for (int i = 0; i < 100; i++) { 
       Thread.sleep(100); 
       publish(i); 
      } 
      return null; 
     } 

     protected void process(List<Integer> progress) { 
      System.out.println(str + " " + progress.get(progress.size() - 1)); 
     } 

     @Override 
     protected void done() { 
      System.out.println(str + " is ready"); 
     } 

    } 

} 

अग्रिम धन्यवाद के उन लोगों के लिए कोड है, पीटर बार्टोलो

+1

हमें दिखा रहा है कि कुछ कोड हमें आपकी मदद कर सकते हैं – karoberts

+0

हाँ मैंने एक बहुत ही सरल प्रोग्राम पोस्ट किया जो समस्या का प्रदर्शन करता है –

+0

कोई भी अपनी मशीन पर समस्या को दोहराने में कामयाब रहा? –

उत्तर

4

जाहिर है, SwingWorker रों डिफ़ॉल्ट रूप से सभी JDK में एक ही पृष्ठभूमि धागे पर अमल 1,6

इन

import java.util.concurrent.Executor; 
import java.util.concurrent.Executors; 
जोड़े

अपने Main() के शीर्ष पर इस

final Executor executor = Executors.newCachedThreadPool(); 

जोड़ सकते हैं और अपने actionPerformed रों में, इस

executor.execute(new Main.MyTask("First")); 

इस तरह अपने SwingWorker रों निष्पादित एक धागा पूल में एक अलग थ्रेड पर प्रत्येक SwingWorker निष्पादित करेंगे।

+0

एक हजार धन्यवाद एम 8, यह अब काम करता है :) –

+0

खुशी मैं मदद कर सकता था – karoberts

संबंधित मुद्दे