[英]Java lock (synchronize) global variable
我有一個密碼
public class Exec {
private String string = "";
public void start() {
MyThread t = new MyThread();
MyThread2 t2 = new MyThread2();
t.start();
t2.start();
}
private class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
string = "1";
System.out.println(string);
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private class MyThread2 extends Thread {
@Override
public void run() {
for (int i = 0; i < 10; i++) {
string = "2";
System.out.println(string);
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
這沒什么難的。 2個線程打印一個值。
輸出:
1
2
1
2
1
...
問題我如何鎖定全局變量(資源)? 輸出:
1
1
1
1
...
2
2
2
2
...
在啟動第二個線程之前(或在啟動之后,但進入for
循環之前),您可以調用t.join()
,它將阻塞直到完成t
。
簡單的解決方案是將start()
更改為run()
因為您實際上不需要多個線程。
但是你可以使用這個
synchronized(Exec.class) {
要么
synchronized(System.out) {
作為共享的全局對象,也可以傳遞此類對象。
只需創建一個鎖變量並鎖定該變量即可。
public class Exec {
private String string = "";
private Object globalLock = new Object(); // The global lock
public void start() {
MyThread t = new MyThread(globalLock);
MyThread2 t2 = new MyThread2(globalLock);
t.start();
t2.start();
}
private class MyThread extends Thread {
private Object lock;
public MyThread(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized(lock) {
for (int i = 0; i < 10; i++) {
string = "1";
System.out.println(string);
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
private class MyThread2 extends Thread {
private Object lock;
public MyThread2(Object lock) {
this.lock = lock;
}
@Override
public void run() {
synchronized(lock) {
for (int i = 0; i < 10; i++) {
string = "2";
System.out.println(string);
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
class Exec{
private String string = "";
Object lock = new Object();
public void start() {
MyThread t = new MyThread();
MyThread2 t2 = new MyThread2();
t.start();
t2.start();
}
public static void main(String[] args) {
new MyServer().start();
}
private class MyThread extends Thread {
@Override
public void run() {
synchronized (lock) {
for (int i = 0; i < 10; i++) {
string = "1";
System.out.println(string);
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
private class MyThread2 extends Thread {
@Override
public void run() {
synchronized (lock) {
for (int i = 0; i < 10; i++) {
string = "2";
System.out.println(string);
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
雖然當您要順序執行代碼塊時使用多線程沒有意義,但是仍然可以通過多種方式解決此問題。 您可以使用鎖定機制(內部,外部,任何Lock
接口實現等),同步器等。IMO最簡單的方法是使用volatile變量:
public class Exec{
private volatile boolean lock = false;
private String string = "";
public void start() {
MyThread t = new MyThread();
MyThread2 t2 = new MyThread2();
lockResource();
t.start();
t2.start();
}
void lockResource() {
lock = true;
}
void releaseResource() {
lock = false;
}
private class MyThread extends Thread {
@Override
public void run() {
while (!lock) ;
for (int i = 0; i < 10; i++) {
string = "1";
System.out.println(string);
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
releaseResource();
}
}
private class MyThread2 extends Thread {
@Override
public void run() {
while (lock) ;
for (int i = 0; i < 10; i++) {
string = "2";
System.out.println(string);
try {
sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
由於布爾變量lock
為false,因此第一個線程將繼續打印,而其他線程具有while循環以保持等待狀態。 一旦第一個線程完成,它將布爾值設置為true,並且由於lock
是易失的,其他線程也將看到此更改。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.