2012-07-21 12 views
6

मेरे एंड्रॉइड प्रोग्राम में एक गतिविधि एक नई सतह दृश्य कक्षा कहती है, जो बदले में एक नई थ्रेड क्लास को कॉल करती है। मैं गतिविधि के ऑन पॉज़ और ऑनयूज़ विधियों से थ्रेड क्लास के लिए एक मान पास करने में सक्षम होना चाहता हूं, इसलिए मैं धागे को रोक और फिर से शुरू कर सकता हूं। इस डेटा को पारित करने का एकमात्र तरीका एक नया उदाहरण बनाकर है, जो सिर्फ एक अलग धागा बना देगा। नया थ्रेड इंस्टेंस बनाने के बिना मुझे इसके बारे में कैसे जाना चाहिए?थ्रेड के बाद गतिविधि से थ्रेड तक एक मान पास कर रहा है

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(new GameSurface(this)); 
} 

@Override 
protected void onResume() { 
    super.onResume(); 
      //Would like to pass this value 
      int state = 1; 
} 

@Override 
protected void onPause() { 
    super.onPause(); 
      //Would like to pass this value 
      int state = 2; 
} 
+0

मैंने अपना जवाब 2 वर्गों और 'परमाणु इंटेगर' के एक कार्यान्वयन कार्यान्वयन के साथ अद्यतन किया है। सादर – Killrawr

उत्तर

4

संगामिति

संगामिति में मानों पासिंग पर एक छोटी सी पृष्ठभूमि आसान हिस्सा है। AtomicInteger डेटा प्रकार (अधिक जानकारी here) में देखें। परमाणुता का अर्थ है All or nothing। यह डेटा प्रकार आवश्यक रूप से धागे या प्रोसेसर के बीच डेटा नहीं भेज रहा है (जैसे आप mpi के साथ) लेकिन यह केवल साझा साझा मेमोरी पर डेटा साझा कर रहा है।

लेकिन क्या एक परमाणु कार्रवाई है? ....

एक परमाणु आपरेशन एक ऑपरेशन जो अन्य कार्यों से हस्तक्षेप की संभावना के बिना काम की एक इकाई के रूप में किया जाता है है।

जावा में भाषा विनिर्देश गारंटी देता है कि एक चर को पढ़ने या लिखना परमाणु है (जब तक वेरिएबल लंबे या दो प्रकार का नहीं होता)। अगर वे के रूप में अस्थिर ....

क्रेडिट (Java Concurrency/Multithreading - Tutorial लार्स वोगेल द्वारा)

मैं अत्यधिक आप यह पढ़ की सिफारिश घोषित लांग और डबल केवल परमाणु हैं, यह atomicity से सब कुछ, thread pools, deadlocks को शामिल किया गया और the "volatile" and "synchronized" keyword


प्रारंभ कक्षायह एक नया धागा (यह भी हमारे Main Thread के रूप में भेजा जा सकता है) पर अमल होगा।

import java.util.concurrent.atomic.AtomicInteger; 
/** 
* @author Michael Jones 
* @description Main Thread 
*/ 
public class start { 
    private AtomicInteger state; 
    private Thread p; 
    private Thread r; 
    /** 
    * constructor 
    * initialize the declared threads 
    */ 
    public start(){ 
     //initialize the state 
     this.state = new AtomicInteger(0); 
     //initialize the threads r and p 
     this.r = new Thread(new action("resume", state)); 
     this.p = new Thread(new action("pause", state)); 
    } //close constructor 

    /** 
    * Start the threads 
    * @throws InterruptedException 
    */ 
    public void startThreads() throws InterruptedException{ 
     if(!this.r.isAlive()){ 
      r.start(); //start r 
     } 
     if(!this.p.isAlive()){ 
      Thread.sleep(1000); //wait a little (wait for r to update)... 
      p.start(); //start p 
     } 
    } //close startThreads 

    /** 
    * This method starts the main thread 
    * @param args 
    */ 
    public static void main(String[] args) { 
     //call the constructor of this class 
     start s = new start(); 
     //try the code 
     try { 
      s.startThreads(); 
     } catch (InterruptedException e) { 
      // TODO Auto-generated catch block 
      e.printStackTrace(); 
     } //start the threads 
    } //close main 

} //close class start 

क्योंकि पूर्णांक परमाणु है, आप भी इसे कहीं भी प्राप्त कर सकते हैं लेकिन प्रारंभ कक्षा में main methodSystem.out.println("[run start] current state is... "+state.intValue()); साथ। (आप main method से इसे पुनः प्राप्त करना चाहते हैं, तो आप सेटअप करना होगा एक सेटर/मनुष्य, जैसे मैं कार्रवाई कक्षा में ऐसा करने के बाद)

कार्रवाई कक्षाइस कार्रवाई में हमारे धागा है (इसे हमारे Slave Thread के रूप में भी संदर्भित किया जा सकता है)।

import java.lang.Thread.State; 
import java.util.concurrent.atomic.AtomicInteger; 

/** 
* @author Michael Jones 
* @description Slave Thread 
*/ 
public class action implements Runnable { 

    private String event = ""; 
    private AtomicInteger state; 

    /** 
    * The constructor (this represents the current instance of a thread). 
    * 
    * @param event 
    * @param state 
    */ 
    public action(String event, AtomicInteger state) { 
     this.event = event; // update this instance of event 
     this.state = state; // update this instance of state 
    } // constructor 

    /** 
    * This method will be called after YourThreadName.Start(); 
    */ 
    @Override 
    public void run() { 
     if (this.event == "resume") { 
      this.OnResume(); // call resume 
     } else { 
      this.OnPause(); // call pause 
     } 
    } // close Runnable run() method 

    /** 
    * The resume function Use the auto lock from synchronized 
    */ 
    public synchronized void OnResume() { 
     System.out.println("[OnResume] The state was.." + this.getAtomicState() 
       + " // Thread: " + Thread.currentThread().getId()); 
     this.setAtomicState(2); // change the state 
     System.out.println("[OnResume] The state is.." + this.getAtomicState() 
       + " // Thread: " + Thread.currentThread().getId()); 
    } // close function 

    /** 
    * The pause function Use the auto lock from synchronized 
    */ 
    public synchronized void OnPause() { 
     System.out.println("[OnPause] The state was.." + this.getAtomicState() 
       + " // Thread: " + Thread.currentThread().getId()); 
     this.setAtomicState(1); // change the state 
     System.out.println("[OnPause] The state is.." + this.getAtomicState() 
       + " // Thread: " + Thread.currentThread().getId()); 
    } // close function 

    /** 
    * Get the atomic integer from memory 
    * 
    * @return Integer 
    */ 
    private Integer getAtomicState() { 
     return state.intValue(); 
    }// close function 

    /** 
    * Update or Create a new atomic integer 
    * 
    * @param value 
    */ 
    private void setAtomicState(Integer value) { 
     if (this.state == null) { 
      state = new AtomicInteger(value); 
     } else 
      state.set(value); 
    } // close function 

} // close the class 

कंसोल आउटपुट

[OnResume] The state was..0 // Thread: 9 
[OnResume] The state is..2 // Thread: 9 
[OnPause] The state was..2 // Thread: 10 
[OnPause] The state is..1 // Thread: 10 

आप देख सकते हैं, AtomicInteger state स्मृति में हमारे सूत्र r और p के बीच साझा किया जा रहा है।


समाधान और चीजें देखने के लिए के लिए ...

केवल एक चीज आप को देखने के लिए जब संगामिति कर Race Conditions/Deadlocks/Livelocks है। कुछ RaceConditions इसलिए होते हैं क्योंकि Threads यादृच्छिक क्रम में बनाए जाते हैं (और अधिकांश प्रोग्रामर अनुक्रमिक क्रम के दिमाग सेट में सोचते हैं)।

मैं लाइन Thread.sleep(1000); है ताकि मेरे Main Thread गुलाम धागा r धागे की state (p चलाने के लिए अनुमति देने से पहले), की वजह से यादृच्छिक क्रम अपडेट होने में थोड़ा समय देता है।

1) धागे का संदर्भ रखें और विधि को विधि के साथ पास करें। क्रेडिट (SJuan76, 2012)

समाधान मैं पोस्ट किया है मैं कर मेरी Main Thread (उर्फ class start) अपने मुख्य संदेश वाहक मेरे दास (उर्फ class action) का उपयोग करने के लिए Atomic Integer का ट्रैक रखने के रूप में। मेरा मुख्य धागा भी updatingmemory buffer के लिए मेरे दास पर (मेमोरी बफर पर अद्यतन एप्लिकेशन की पृष्ठभूमि में होता है और AtomicInteger कक्षा द्वारा नियंत्रित किया जाता है)

+0

धन्यवाद। तो क्या मुझे अपडेटेड स्टेटस प्राप्त करने के लिए थ्रेड क्लास में एटमिक इंटेगर कन्स्ट्रक्टर या विधि का उपयोग करना होगा? क्षमा करें अगर यह सही नहीं है। जावा मेरे लिए काफी नया है। – zkello

+0

आपको प्रत्येक वर्ग में परमाणु इंटेगर घोषणा का उपयोग करना है (कहें कि मेरे पास कक्षा 'foo' है जो वर्ग' बू 'के साथ धागा बनाता है) मुझे साझा करने के क्रम में दोनों वर्गों में घोषित मेरे' परमाणु इंटेगर x' की आवश्यकता होगी स्मृति में – Killrawr

+0

अपने 'ऑन पॉज़()' और 'ऑनर्यूम()' में 'सिंक्रनाइज़' भी जोड़ें, उदाहरण के लिए 'संरक्षित सिंक्रनाइज़ेड शून्य ऑनर्यूम() '। यह थ्रेड या वैरिएबल 'स्टेट' पर ऑटो लॉकिंग को सक्षम बनाता है। और एक संभावित 'रेस कंडीशन' से बच जाएगा। – Killrawr

3

1) धागे का संदर्भ रखें और विधि को विधि के साथ पास करें।

2) थ्रेड निर्माण के दौरान, इसे गतिविधि के साथ साझा की गई वस्तु को पास करें। मूल्यों को ऑब्जेक्ट में पास करने के लिए रखें, थ्रेड को नियमित रूप से जांचें जब तक कि मान नहीं मिल जाते।

+0

पहला समाधान संभावित दौड़ की स्थिति का कारण नहीं होगा? यदि या तो 'ऑनर्यूम' या 'ऑन पॉज़' एक दूसरे पर भरोसा करते हैं? – Killrawr

1

मैं संदर्भ वर्ग का उपयोग करता हूं जिसे मैं Share Class नाम देता हूं। इसमें volatile प्रकार के साथ चर है।

अस्थिर दर्शाता है कि एक वेरिएबल का मान अलग धागे द्वारा संशोधित किया जाएगा प्रयोग किया जाता है।

public class Share { 
    public static volatile type M_shared; 
} 

इस चर बदलने के लिए, आप उसे लॉक कर देना चाहिए और परिवर्तन मूल्य के बाद, अवरोध खोल। आप Share.M_shared का उपयोग करके पढ़ और लिख सकते हैं।

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