我有一个代码
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
...
答案 0 :(得分:1)
在开始第二个线程之前(或者在启动它之后,但在进入for
循环之前),您可以调用t.join()
,它将阻塞,直到t
完成。
答案 1 :(得分:1)
简单的解决方案是将start()
更改为run()
,因为您实际上并不想要多个线程。
但是你可以使用这个
synchronized(Exec.class) {
或
synchronized(System.out) {
作为共享的全局对象,或者您可以传递这样的对象。
答案 2 :(得分:0)
只需创建一个锁变量并锁定此变量。
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();
}
}
}
}
}
}
答案 3 :(得分:0)
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();
}
}
}
}
}
}
答案 4 :(得分:0)
虽然当您想要按顺序执行代码块时使用多线程没有意义,但如果您需要它,您仍可以通过多种方式解决此问题。您可以使用锁定机制(内部,外部,任何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循环以保持等待。完成第一个线程后,它会将boolean设置为true,其他线程也会看到此更改,因为lock
是不稳定的。