java - 在创建线程后将值从 Activity 传递到线程

标签 java android multithreading android-activity

在我的 android 程序中,一个 Activity 调用一个新的表面 View 类,然后它又调用一个新的线程类。我希望能够从 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;
}

最佳答案

并发的一些背景知识

并发传递值是比较容易的部分。查看 AtomicInteger 数据类型(更多信息 here)。原子性也意味着 All or nothing。这种数据类型不一定在线程或处理器之间发送数据(就像您使用 mpi 那样),它只是在其共享内存上共享数据。

但是什么是原子操作?....

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)

我强烈推荐你阅读这篇文章,它涵盖了从原子性线程池死锁“volatile”和“同步”关键字


开始类 这将执行一个新线程(它也可以称为我们的主线程)。

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

因为整数是原子的,所以您还可以在 Start Class 中的 main 方法 之外的任何地方使用 System.out.println( "[run start] current state is... "+state.intValue());.(如果你想从 main 方法中检索它,你将必须设置一个 Setter/Getter,就像我在 Action Class 中所做的那样)

Action 类 这是我们正在运行的线程(它也可以称为我们的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 状态 在我们的线程 rp 之间的内存中共享。


解决方案和需要寻找的东西...

在进行并发时,您唯一需要注意的是竞争条件/死锁/活锁。一些 RaceConditions 的发生是因为 Threads 是按随机顺序创建的(而且大多数程序员以顺序顺序的思维方式思考)。

我有 Thread.sleep(1000); 行,这样我的 Main Thread 就会给从属线程 r 一点时间来更新状态(在允许 p 运行之前),由于线程的随机顺序

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

在我发布的解决方案中,我将我的Main Thread(又名class start)作为我的主要通信器来跟踪Atomic Integer 供我的奴隶使用(又名 class action)。我的主线程也在为我的从服务器上的原子整数更新内存缓冲区(内存缓冲区的更新发生在应用程序的背景,由 AtomicInteger 类处理)

关于java - 在创建线程后将值从 Activity 传递到线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11596708/

相关文章:

python - 单生产者多消费者

mysql - 刷新线程中的查询

java - 获取输入字的 ASCII 值

java - `create` Cordova Android 脚本无法创建新项目 - java/ant 配置错误

android - 如何防止后退按钮杀死 TextView 详细信息

android - 如何在android中找到给定的位图图像是模糊图像还是未模糊图像

java - Android URISyntaxException 索引 53 处查询中存在非法字符

java - 错误消息 “Illegal Start of Expression”?

java - 运行现有 spring boot gradle 项目时出现问题

c++ - 使用无锁指针队列在线程之间移动数据是否安全