在我的 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 状态
在我们的线程 r
和 p
之间的内存中共享。
解决方案和需要寻找的东西...
在进行并发时,您唯一需要注意的是竞争条件
/死锁
/活锁
。一些 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/