线程同步,就是线程之间互相协调,通过等待,唤醒等操作,避免线程之间同时操作同一个资源。简单的说就是线程之间互相协作,避免干扰了其他线程的工作。
Java 线程中,有多种方式可以实现线程同步,wait/notify 方法是最常用的一种方式。
实现 2 个线程,一个线程只能打印奇数,另一个线程只能打印偶数,现在需要打印出 1234…..100 这样的数列。
下面代码的一种实现方式,未有任何同步机制,所以两个线程不可能交替运行。
public static void main(String args[]) throws Exception {
FutureTask task1=new FutureTask(()->{
for(int i=0;i<50;i++)
{
System.out.print(i*2+1+",");
}
return null;
});
Thread t1=new Thread(task1);
FutureTask task2=new FutureTask(()->{
for(int i=0;i<50;i++)
{
System.out.print(i*2+2+",");
}
return null;
});
Thread t2=new Thread(task2);
t1.start();
t2.start();
t1.join();
t2.join();
}
下面的代码,通过 synchronized 关键字,wait 方法阻塞,notify 方法唤醒的方式,实现线程之间的通信。
public static void main(String args[]) throws Exception {
Object lock = new Object();
final boolean[] flag = {true};//交替执行标志位。true-线程1运行,false-线程2运行
FutureTask task1 = new FutureTask(() -> {
for (int i = 0; i < 50; i++) {
synchronized (lock) {
while (true) {
if (flag[0]) {
System.out.print(i * 2 + 1 + ",");
flag[0] = false;
lock.notify();
if (i < 49) {//打印完最后一个,不需要再wait了。
lock.wait();
}
break;
}
}
}
}
return null;
});
Thread t1 = new Thread(task1);
FutureTask task2 = new FutureTask(() -> {
for (int i = 0; i < 50; i++) {
synchronized (lock) {
while (true) {
if (!flag[0]) {
System.out.print(i * 2 + 2 + ",");
flag[0] = true;
lock.notify();
if (i < 49) {//打印完最后一个,不需要再wait了。
lock.wait();
}
break;
} else {
lock.wait();
}
}
}
}
return null;
});
Thread t2 = new Thread(task2);
t1.start();
t2.start();
t1.join();
t2.join();
System.out.print("finished");
}