[英]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.