7

私の Android プログラムでは、Activity が新しいサーフェス ビュー クラスを呼び出し、次にそれが新しいスレッド クラスを呼び出します。アクティビティの onPause および onResume メソッドからスレッド クラスに値を渡して、スレッドを一時停止および再開できるようにしたいと考えています。このデータを渡す唯一の方法は、別のスレッドを作成する新しいインスタンスを作成することです。新しいスレッド インスタンスを作成せずにこれを行うにはどうすればよいですか?

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;
}
4

3 に答える 3

5

同時実行の背景

並行して値を渡すのは簡単です。データ型を調べAtomicIntegerます (詳細はこちら)。原子性も意味しAll or nothingます。このデータ型は、( の場合のように) スレッド間またはプロセッサ間で必ずしもデータを送信するわけではありませんがmpi、共有メモリでデータを共有しているだけです。

しかし、アトミックアクションとは何ですか?...

アトミック操作とは、他の操作から干渉される可能性がなく、単一の作業単位として実行される操作です。

Java では、変数の読み取りまたは書き込みがアトミックであることを言語仕様が保証しています (変数が long または double 型でない限り)。long と double は、volatile として宣言されている場合にのみアトミックです....

クレジット ( Java Concurrency / Multithreading - Lars Vogel によるチュートリアル)

これを読むことを強くお勧めします。 atomicitythread poolsdeadlocksおよびthe "volatile" and "synchronized" keyword.


Start Class これは新しいスレッドを実行します(私たちの とも呼ばれます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 methodStart Class with以外の場所で取得することもできますSystem.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 Threadrstatep

1) スレッドへの参照を保持し、メソッドで値を渡します。 クレジット ( SJuan76、2012)

私が投稿したソリューションでは、スレーブが使用する (aka ) を追跡するためのメイン コミュニケーターとしてMain Thread(aka ) を作成します。私のメイン スレッドは、私のスレーブにもあります(メモリ バッファの更新は、アプリケーションのバックグラウンドで発生し、クラスによって処理されます)class startAtomic Integerclass actionupdatingmemory bufferAtomic IntegerAtomicInteger

于 2012-07-21T23:59:15.080 に答える
4

1) スレッドへの参照を保持し、メソッドで値を渡します。

2) スレッドの作成中に、Activity と共有されるオブジェクトをスレッドに渡します。渡す値をオブジェクトに入れ、値が見つかるまでスレッドに定期的にチェックさせます。

于 2012-07-21T23:54:53.057 に答える
2

名前を付けた参照クラスを使用しますShare Class。タイプ付きの変数がありますvolatile

volatileは、変数の値がさまざまなスレッドによって変更されることを示すために使用されます。

public class Share {
   public static volatile type M_shared;
}

この変数を変更するには、それをロックし、値を変更した後、ロックを解除する必要があります。を使用して読み取りと書き込みを行うことができますShare.M_shared

于 2012-07-22T00:31:33.090 に答える