Một nền nhỏ trên đồng thời
Đi qua giá trị trong đồng thời là phần dễ dàng. Nhìn vào loại dữ liệu AtomicInteger
(Thông tin thêm here). Nguyên tử cũng có nghĩa là All or nothing
. Kiểu dữ liệu này không nhất thiết phải gửi dữ liệu giữa các luồng hoặc bộ xử lý (như bạn làm với mpi
) nhưng nó chỉ đơn thuần là chia sẻ dữ liệu trên bộ nhớ dùng chung của nó.
Nhưng những gì là một hành động nguyên tử? ....
Một hoạt động nguyên tử là một hoạt động được thực hiện như một đơn vị công việc mà không có khả năng can thiệp từ các hoạt động khác.
Trong Java, đặc tả ngôn ngữ đảm bảo rằng việc đọc hoặc viết biến là nguyên tử (trừ khi biến có kiểu dài hoặc gấp đôi). Long và đôi chỉ nguyên tử nếu họ khai báo là không ổn định ....
tín dụng (Java Concurrency/Multithreading - Tutorial bởi Lars Vogel)
tôi khuyên bạn đọc này, nó bao gồm tất cả mọi thứ từ atomicity
, thread pools
, deadlocks
và the "volatile" and "synchronized" keyword
.
Bắt đầu lớpnày sẽ thực hiện một chủ đề mới (Nó cũng có thể được gọi là Main Thread
của chúng tôi).
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
Bởi vì số nguyên là nguyên tử, bạn cũng có thể lấy nó ở mọi nơi nhưng main method
trong Bắt đầu lớp với System.out.println("[run start] current state is... "+state.intValue());
. (Nếu bạn muốn lấy nó ra khỏi main method
, bạn sẽ phải thiết lập một setter/getter, như tôi đã làm như vậy trong Vụ Kiện Tập Thể)
Vụ Kiện Tập ThểĐây là chủ đề của chúng tôi trong hành động (Nó cũng có thể được gọi là Slave Thread
) của chúng tôi.
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
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
Như bạn có thể thấy, AtomicInteger state
đang được chia sẻ trong bộ nhớ giữa các chủ đề của chúng tôi r
và p
.
Giải pháp và Những điều cần tìm kiếm ...
Điều duy nhất bạn phải xem khi thực hiện đồng thời là Race Conditions
/Deadlocks
/Livelocks
. Một số RaceConditions
xảy ra vì Threads
được tạo theo thứ tự ngẫu nhiên (Và hầu hết các lập trình viên đều nghĩ trong tập hợp thứ tự tuần tự).
Tôi có dòng Thread.sleep(1000);
để Main Thread
tôi cung cấp cho các chủ đề nô lệ r
một ít thời gian để cập nhật các state
(trước khi cho phép p
để chạy), do thứ tự ngẫu nhiên của bài.
1) Giữ tham chiếu đến chuỗi và chuyển giá trị bằng phương pháp. tín dụng (SJuan76, 2012)
Trong giải pháp tôi đã đăng tôi làm cho tôi Main Thread
(aka class start
) như giao tiếp chính của tôi để theo dõi các Atomic Integer
cho nô lệ của tôi để sử dụng (aka class action
). Chủ đề chính của tôi cũng là updating
memory buffer
cho số Atomic Integer
trên nô lệ của tôi (Bản cập nhật trên bộ nhớ đệm xảy ra trong nền của ứng dụng và được xử lý bởi lớp AtomicInteger
).
Tôi đã cập nhật câu trả lời của mình với 2 lớp và triển khai hoạt động của 'AtomicInteger'. Kính trọng – Killrawr