有一个场景需要实现多线程处理任务完毕后,再串行处理后面的流程。
下面首先介绍的方式,是通过synchronized同步锁来实现,这是一种最基础的方式,后面的文章,我整理其他其他更丰富的方法。
通过synchronized同步锁来实现:
就是放置一个公用的static变量,假如有10个线程,每个线程处理完上去累加下结果,然后后面用一个死循环(或类似线程阻塞的方法),去数这个结果,达到10个,说明大家都执行完了,就可以执行后续的事情了,这个想法虽然土鳖,但是基本上跟语言无关,几乎所有主流编程语言都支持。
下面直接上代码:
public class ThreadLockTest {
public static Integer flag = 0;//公用变量
public static void main(String[] args) throws Exception {
ThreadLockTest testObj = new ThreadLockTest();
final int threadNum = 10;
for (int i = 0; i < threadNum; i++) {
new Thread(new MyRunable(i, testObj)).start();
}
while (true) {
if (testObj.flag >= threadNum) {
System.out.println("-----------\n所有thread执行完成!");
break;
}
Thread.sleep(10);
}
}
static class MyRunable implements Runnable {
int _i = 0;
ThreadLockTest _test;
public MyRunable(int i, ThreadLockTest test) {
this._i = i;
this._test = test;
}
@Override
public void run() {
try {
Thread.sleep((long) (Math.random() * 10));
System.out.println("thread " + _i + " done");
//利用synchronized获得同步锁
synchronized (_test) {
_test.flag += 1;
}
System.out.println("thread " + _i + " => " + _test.flag);//测试用
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
可以看到上面使用synchronized获得同步锁的处理类似下面的代码,其中必须加上synchronized是为了证不会出现并发线程同时访问的情况。
public class Sample1 {
private static Integer count = 0;
synchronized public static void increment() {
count++;
}
}
升级开始,下面再来看一段代码:
public class Sample2 {
private static AtomicInteger count = new AtomicInteger(0);
public static void increment() {
count.getAndIncrement();
}
}
上面使用AtomicInteger中却不用加上synchronized,因为AtomicInteger是一个提供原子操作的Integer类,它是通过线程安全的方式操作加减,因此十分适合高并发情况下的使用。
两相对比下来,是不是使用AtomicInteger更简单呢。下面咱就对最上面的代码,使用AtomicInteger优化调整一下,于是就有了下面的代码:
import java.util.concurrent.atomic.AtomicInteger;
public class ThreadAtomTest {
public static AtomicInteger atomicInteger = new AtomicInteger(0);
public static void main(String[] args) throws Exception {
final int threadNum = 10;
for (int i = 0; i < threadNum; i++) {
new Thread(new ThreadAtomTest.MyRunable(i)).start();
}
while (true) {
if (ThreadAtomTest.atomicInteger.intValue() >= threadNum) {
System.out.println("-----------\n所有thread执行完成!");
break;
}
Thread.sleep(10);
}
}
static class MyRunable implements Runnable {
int _i = 0;
public MyRunable(int i) {
this._i = i;
}
@Override
public void run() {
try {
Thread.sleep((long) (Math.random() * 10));
System.out.println("thread " + _i + " done");
int andIncrement = ThreadAtomTest.atomicInteger.incrementAndGet();
System.out.println("thread " + _i + " => " + andIncrement);//测试用
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
网友评论