使用三个线程,调用foo的不同方法按线程执行的顺序打印first second third内容。
foo类代码如下
class foo {
public foo() {
}
public void printFirst(Runnable runnable) {
runnable.run();
}
public void printSecond(Runnable runnable) {
runnable.run();
}
public void printThird(Runnable runnable) {
runnable.run();
}
}
方案1 volatile+自旋锁
使用volatile关键字实现,volatile关键字保证线程间数据的可见性,具体讲的话就是使用volatile关键字每个线程执行完毕都会将当前的工作内存中的数据强制刷入到主内存中,以实现数据的可见性,保证多线程间数据的共享。
实现代码如下:
class foo {
volatile int flag=0;
public foo() {
}
public void printFirst(Runnable runnable) {
while(flag!=0){
}
runnable.run();
flag=1;
}
public void printSecond(Runnable runnable) {
while(flag!=1){}
runnable.run();
flag=2;
}
方案2 加锁同步
使用synchronized实现加锁同步,具体使用的是对象锁synchronized(this),其含义是进入同步代码块的线程对象会被锁住,满足条件执行,不满足条件阻塞。
class foo {
private boolean firstLock = false;
private boolean secondLock = false;
public foo() {
}
public void printFirst(Runnable runnable) {
synchronized (this) {
runnable.run();
firstLock = true;
this.notifyAll();
}
}
public void printSecond(Runnable runnable) {
synchronized (this) {
while (!firstLock) {
try {
this.wait();
} catch (Exception e) {
e.printStackTrace();
}
}
runnable.run();
secondLock = true;
this.notifyAll();
}
}
public void printThird(Runnable runnable) {
synchronized (this) {
while (!secondLock) {
try {
this.wait();
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
runnable.run();
}
}
}
对synchronized(this)的理解,该同步加的是对象锁[1]。
1)如果多个线程对一个方法中的synchronized同步代码块进行访问的时候,只有一个线程可以执行,其他线程处于阻塞状态。
2)如果多个线程中,一个线程对synchronized代码块进行访问,而另外的线程对其非同步代码块的方法进行访问,不会阻塞。
3)如果多个线程同时对多个有同步代码块的方法进行访问的时候,只有一个线程能够执行,其他线程处于阻塞状态。
4)以上规则对其它对象锁同样适用.。即synchronized(this)==synchronized(obj)。
3.使用源自类CAS乐观锁实现
使用原子类AtomicInteger的CAS锁完成顺序打印,使用其compareAndSet(expect,update)方法实现,该方法的意义就是如果当前的值与expect相同,则完成更新update。
class foo {
private AtomicInteger i;
public foo() {
i=new AtomicInteger(1);
}
public void printFirst(Runnable runnable) {
while(!i.compareAndSet(1,2)){
}
runnable.run();
}
public void printSecond(Runnable runnable) {
while(!i.compareAndSet(2,3)){
}
runnable.run();
}
public void printThird(Runnable runnable) {
while(!i.compareAndSet(3,4)){
}
runnable.run();
}
}
main方法中的代码
public class inOrderPrint {
public static void main(String[] args) {
foo foo = new foo();
new Thread(() -> {
foo.printFirst(() -> System.out.println("first"));
}).start();
new Thread(() -> {
foo.printSecond(() -> System.out.println("second"));
}).start();
new Thread(() -> {
foo.printThird(() -> System.out.println("third"));
}).start();
}
}
参考资料:
[1]对synchronized(this)的一些理解