如何让两个线程同时执行?
public class threadTest {
public static void main(String[] args) {
Thread A = new Thread(new Runnable() {
@Override
public void run() {
printNumber("A");
}
});
Thread B = new Thread(new Runnable() {
@Override
public void run() {
printNumber("B");
}
});
A.start();
B.start();
}
public static void printNumber(String s) {
int i = 0;
while (i++ < 3) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(s + "===print:" + i);
}
}
}
多次输出结果(观察下面几张图的不同点与相同点):
我们可以看出,A、B线程是同时执行的。
如何等待一个线程执行完毕再执行另外一个?
public class threadTest {
public static void main(String[] args) {
Thread A = new Thread(new Runnable() {
@Override
public void run() {
printNumber("A");
}
});
Thread B = new Thread(new Runnable() {
@Override
public void run() {
System.out.println("B开始等待A线程");
try {
A.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
printNumber("B");
}
});
A.start();
B.start();
}
public static void printNumber(String s) {
int i = 0;
while (i++ < 3) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(s + "===print:" + i);
}
}
}
输出结果:
观察结果,可以看到在B线程中先输出了一句“B开始等待A线程”,然后A线程开始执行,A线程执行完毕最后B线程开始执行,之所以会这样,因为我们加了这句代码,A.join();
join()方法的作用是使当前的线程停止下来,等待调用的线程执行完毕后再执行自身线程。(使得线程之间的并行操作暂时改变为串行操作)
如何让两个线程按照指定顺序交叉执行?
如果想要按照自己定义的顺序执行线程,依赖于join()是不行的,得需要更细粒度的去控制线程的执行顺序。
public class threadTest {
public static void main(String[] args) {
Object lock = new Object();
Thread A = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock) {
System.out.println("A1");
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("A2");
System.out.println("A3");
}
}
});
Thread B = new Thread(new Runnable() {
@Override
public void run() {
synchronized(lock) {
System.out.println("B1");
System.out.println("B2");
System.out.println("B3");
lock.notify();
}
}
});
A.start();
B.start();
}
}
输出结果:
解释下输出结果:
首先两个线程A、B共用一个对象锁,当A线程开始执行时将对象锁取走,此时B线程处于等待状态;A线程输出A1后调用方法wait(),使自身线程进入等待状态,释放对对象锁的持有权,此时B线程获得对象锁开始执行线程,分别输出B1、B2、B3,输出完毕后B线程调用notify()方法唤醒处于等待状态的A线程,A线程继续执行输出A2、A3。
如何使一个线程等待多个线程?
前面用到的join()方法可以使得当前线程等待其他线程,那如果需要等待多个线程该怎么办呢,我们可以用CountDownLatch。
public class threadTest {
public static void main(String[] args) {
int count = 3;
CountDownLatch countDownLatch = new CountDownLatch(count);
new Thread(new Runnable() {
@Override
public void run() {
System.out.println("当前线程为D线程,等待其他3个线程。");
try {
countDownLatch.await();
System.out.println("其他3个线程已执行完毕,D线程开始...");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
for(char threadName='A';threadName <='C';threadName++) {
String name= String.valueOf(threadName);
new Thread(new Runnable() {
@Override
public void run() {
System.out.println(name + "线程开始执行");
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "线程执行完毕");
countDownLatch.countDown();
}
}).start();
}
}
}
CountDownLatch相当于一个计数器,首先需要给他初始化一个计数值,当其他线程执行时我们可以递减这个计数值,当这个计数值减到0时,当前线程就可以继续执行了。
countDownLatch.await() 检查计数值是否为0,不为0时继续等待,为0时开始执行。
countDownLatch.countDown() 逐渐计数值,每次减。
CountDownLatch使用于一个线程等待多个线程的场景。