多线程顺序打印

使用三个线程,调用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)的一些理解

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值