从活动传递一个值线程已创建的线程后,线程

由网友(-梦死深蓝海@)分享简介:在我的Andr​​oid程序中的活动调用一个新的表面视图类,然后再调用一个新的线程类。我希望能够传递一个值,从活动的的onPause和onResume方法的线程类,这样我就可以暂停和恢复线程。我知道通过这个数据的唯一方法是通过创建一个新的实例,这将只需要创建一个不同的线程。我应该如何去了解这一点没有创建一个新的线程实例...

在我的Andr​​oid程序中的活动调用一个新的表面视图类,然后再调用一个新的线程类。我希望能够传递一个值,从活动的的onPause和onResume方法的线程类,这样我就可以暂停和恢复线程。我知道通过这个数据的唯一方法是通过创建一个新的实例,这将只需要创建一个不同的线程。我应该如何去了解这一点没有创建一个新的线程实例?

 公共无效的onCreate(包savedInstanceState){
    super.onCreate(savedInstanceState);
    的setContentView(新GameSurface(本));
}

@覆盖
保护无效onResume(){
    super.onResume();
            //想通过这个值
            INT状态= 1;
}

@覆盖
保护无效的onPause(){
    super.onPause();
            //想通过这个值
            INT状态= 2;
}
 

解决方案

一个小的背景上并发 线程2 Java多线程状态

在并发传值是比较容易的部分。看看到的AtomicInteger 的数据类型(详细信息的这里)。原子也意味着全有或全无。此数据类型不一定发送线程或处理器之间的数据(就像你使用 MPI ),但它仅仅是分享关于其共享内存中的数据。

但是,什么是一个原子操作?....

  

这是原子操作是它不受其他业务干扰的可能性进行的工作的一个单元的操作。

     

在Java语言规范保证读取或写入的变量是原子(除非该变量的类型是长或双)。龙和双只原子的,如果他们声明为volatile ......

     

信贷( Java并发/多线程 - 通过教程拉尔斯·沃格尔)的

我强烈建议您阅读本文,它涵盖了从原子线程池死锁的动荡和同步关键字

开始授课的这将执行一个新的线程的(它也可以被称为我们的主线

 进口java.util.concurrent.atomic.AtomicInteger中;
/ **
 * @author迈克尔·琼斯
 * @description主线程
 * /
公共类开始{
    私人的AtomicInteger状态;
    私人线程p;
    私人螺纹R;
    / **
     *构造函数
     *初始化声明线程
     * /
    公众的start(){
        //初始化状态
        this.state =新的AtomicInteger(0);
        //初始化线程 -  [R和P
        this.r =新主题(新动作(恢复,状态));
        this.p =新主题(新动作(暂停,状态));
    } //关闭构造

    / **
     *启动线程
     * @throws InterruptedException的
     * /
    公共无效startThreads()抛出InterruptedException的{
        如果(!this.r.isAlive()){
            r.start(); //启动ṛ
        }
        如果(!this.p.isAlive()){
            视频下载(1000); //等待一小(等待r以更新)...
            p.start(); //启动p
        }
    } //关闭startThreads

    / **
     *此方法从主线程
     * @参数ARGS
     * /
    公共静态无效的主要(字串[] args){
         //调用这个类的构造函数
        启动S =新的开始();
        //尝试code
        尝试 {
            s.startThreads();
        }赶上(InterruptedException异常E){
            // TODO自动生成的catch块
            e.printStackTrace();
        } //启动线程
    } //关闭主

} //关闭开课
 

由于整数是原子,你也可以在任何地方获取,但在开始授课的主要方法的System.out.println([运行启动]目前的状态是...+ state.intValue()); 的(如果你想从检索。 主要方法,你将不得不设置一个二传手/吸气,就像我在做这样的 Action类)

Action类的这是我们在行动主题的(它也可以被称为我们的从线程

 进口java.lang.Thread.State中;
进口java.util.concurrent.atomic.AtomicInteger中;

/ **
 * @author迈克尔·琼斯
 * @description从属线程
 * /
公众集体诉讼实现Runnable {

    私人字符串事件=;
    私人的AtomicInteger状态;

    / **
     *构造函数(这种重presents线程的当前实例)。
     *
     * @参数事件
     * @参数状态
     * /
    公益行动(String事件,的AtomicInteger州){
        this.event =事件; //更新事件的这个实例
        this.state =状态; //更新状态的这个实例
    } //构造函数

    / **
     *这个方法将YourThreadName.Start后,被称为();
     * /
    @覆盖
    公共无效的run(){
        如果(this.event ==恢复){
            this.OnResume(); //呼叫恢复
        } 其他 {
            this.OnPause(); //调用暂停
        }
    } //关闭Runnable的run()方法

    / **
     *恢复功能使用的同步自动锁定
     * /
    市民同步无效OnResume(){
        的System.out.println([OnResume]国家是..+ this.getAtomicState()
                +//主题:+ Thread.currentThread()的getId());
        this.setAtomicState(2); //改变状态
        的System.out.println([OnResume]的状态。+ this.getAtomicState()
                +//主题:+ Thread.currentThread()的getId());
    } //关闭功能

    / **
     *暂停功能使用从同步自动锁定
     * /
    市民同步无效将OnPause(){
        的System.out.println([将OnPause]国家是..+ this.getAtomicState()
                +//主题:+ Thread.currentThread()的getId());
        this.setAtomicState(1); //改变状态
        的System.out.println([将OnPause]的状态。+ this.getAtomicState()
                +//主题:+ Thread.currentThread()的getId());
    } //关闭功能

    / **
     *从内存中的原子整数
     *
     返回:整数
     * /
    私人整数getAtomicState(){
        返回state.intValue();
    } //关闭功能

    / **
     *更新或创建新的原子整数
     *
     *参数值
     * /
    私人无效setAtomicState(整数值){
        如果(this.state == NULL){
            状态=新的AtomicInteger(值);
        } 其他
            state.set(值);
    } //关闭功能

} //关闭类
 

控制台输出

  [OnResume]国家was..0 //主题:9
[OnResume]国家is..2 //主题:9
[将OnPause]国家was..2 //主题:10
[将OnPause]国家is..1 //主题:10
 

正如你所看到的,的AtomicInteger状态正在我们的线程之间的内存共享研究 P

解决方案和事情,寻找...

您必须注意在做并发竞争条件 / 死锁 / 活锁。有些 RaceConditions 发生,因为主题按照随机顺序创建(而且大多数程序员认为,在思维定势的顺序排列)。

我也行视频下载(1000); 让我的主线给出了从线程研究一点时间来更新状态(才让 P 运行)的由于随机顺序线程的。

  

1)保持一个参考给线程和传递值用的方法。   信用卡( SJuan76 ,2012)的

在我已为我做的解决方案,我的主线(又名类开始)作为我的主要传播者跟踪的原子整数我的奴隶使用(又名集体诉讼)的。我的主线程也是更新内存缓冲区原子整数在我的奴隶的(在内存缓冲区更新发生在应用程序的背景下,由的AtomicInteger 类处理)。

In my android program an Activity calls a new surface view class, which then in turn calls a new thread class. I want to be able to pass a value to the thread class from the activity's onPause and onResume methods, so I can pause and resume the thread. The only way I know to pass this data is by creating a new instance, which would just create a different thread. How should I go about this without creating a new thread instance?

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

解决方案

A little background on concurrency

Passing values in concurrency is the easy part. Look into the AtomicInteger data type (More information here). Atomicity also means All or nothing. This data type isn't necessarily sending data between threads or processors (like you would with mpi) but it is merely sharing data on its shared memory.

But what is an Atomic Action?....

An atomic operation is an operation which is performed as a single unit of work without the possibility of interference from other operations.

In Java the language specification guarantees that reading or writing a variable is atomic (unless the variable is of type long or double). Long and double are only atomic if they declared as volatile....

Credit(Java Concurrency / Multithreading - Tutorial by Lars Vogel)

I highly recommend you read this, it covers everything from atomicity, thread pools, deadlocks and the "volatile" and "synchronized" keyword.

Start Class This will execute a new thread (It can also be referred to as our 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

Because the integer is atomic, you can also retrieve it anywhere but the main method in the Start Class with System.out.println("[run start] current state is... "+state.intValue());. (If you wish to retrieve it from the main method, you will have to setup a Setter/Getter, like I've done so in the Action Class)

Action Class This is our thread in action (It can also be referred to as our 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

The Console Output

[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

As you can see, the AtomicInteger state is being shared in the memory between our threads r and p.

Solution and Things to look for...

The only thing you have to watch when doing concurrency is Race Conditions/Deadlocks/Livelocks. Some RaceConditions occur because Threads are created in random order (And most programmers think in the mind set of sequential order).

I have the line Thread.sleep(1000); so that my Main Thread gives the slave thread r a little time to update the state (before allowing p to run), due to the random order of threads.

1) Keep a reference to the thread and pass the value with a method. Credit (SJuan76, 2012)

In the solution I've posted I make my Main Thread (aka class start) as my main communicator to keep track of the Atomic Integer for my slaves to use (aka class action). My main thread is also updating the memory buffer for the Atomic Integer on my slaves (The update on the memory buffer occurs in the background of the application and is handled by the AtomicInteger class).

阅读全文

相关推荐

最新文章