下边这段代码,会输出什么?
package com.test.java;
import java.util.concurrent.CountDownLatch;
class MyThread implements Runnable{
private String name;
public MyThread(){}
public MyThread(String name){this.name = name;}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(name + i + " ... ");
}
}
}
public class TestConcurrent2 {
public static void main(String[] args) {
Thread t = new Thread(new MyThread("beckham"));
t.start();
Thread tk = new Thread(new MyThread("kaka"));
tk.start();
}
}
答案是不确定。有可能先输出kaka,也有可能先输出beckham。
但是如果我稍微变一下...
package com.test.java;
import java.util.concurrent.CountDownLatch;
class MyThread implements Runnable{
private String name;
public MyThread(){}
public MyThread(String name){this.name = name;}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
if(name.equals("beckham")){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(name + i + " ... ");
}
}
}
public class TestConcurrent2 {
public static void main(String[] args) {
Thread t = new Thread(new MyThread("beckham"));
t.start();
Thread tk = new Thread(new MyThread("kaka"));
tk.start();
}
}
对的,这下不出意外的话,你答对了,先输出kaka。
但是实际工作中有这样的情况。一段代码有AB两块,A启动了一个线程,B也启动了一个线程。如何保证A完成之后,B线程才开始?(sleep是很糟糕的做法,而且不能保证)
OK, Concurrent包提供的CountDownLatch就是这样一个工具,我对第二段代码继续改造一下 ...
package com.test.java;
import java.util.concurrent.CountDownLatch;
class MyThread implements Runnable{
private String name;
private CountDownLatch end = new CountDownLatch(10);
public MyThread(){}
public MyThread(String name){this.name = name;}
public MyThread(String name, CountDownLatch end) {
this.name = name;
this.end = end;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
if(name.equals("beckham")){
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
end.countDown();
}
}
System.out.println(name + i + " ... ");
}
}
}
public class TestConcurrent2 {
public static void main(String[] args) {
CountDownLatch end = new CountDownLatch(10);
Thread t = new Thread(new MyThread("beckham", end));
t.start();
try {
end.await();
} catch (InterruptedException e) {
e.printStackTrace();
} finally{
Thread tk = new Thread(new MyThread("kaka"));
tk.start();
}
}
}
CountDownLatch就是一个简单的计数器用来约束线程。直到计数器为0. 才肯放行下边的工作 ....XD