synchronized一个有趣现象

如果你不相信努力和时光,那么成果就会是第一个选择辜负你的。不要去否定你自己的过去,也不要用你的过去牵扯你现在的努力和对未来的展望。不是因为拥有希望你才去努力,而是去努力了,你才有可能看到希望的光芒。synchronized一个有趣现象,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

在学习synchronized时发现了一个有趣的现象:

public class MyThread implements  Runnable {
    private int number=10;
    private  boolean flag = true;
    @Override
    public  void run() {
        while (flag) {
            //同步块,()填变化的量必须是引用类型,锁定的就是传入参数
            synchronized (Integer.valueOf(number)){
                number--;
                try {
                    Thread.sleep(1000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (number < 1) {
                    flag=false;
                }
                else {
                    System.out.println(Thread.currentThread().getName() + "--" + number);
                }
            }
            }
        }

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        new Thread(myThread,"李").start();
        new Thread(myThread,"马").start();
        new Thread(myThread,"王").start();
    }
}

/*
李--7
马--7
王--7
王--4
李--4
马--4
李--1
马--1
王--1

我以为只有在一个线程执行完同步块后另外一个线程才有机会进入,但上述情况却像是一旦对同步监视器的相关操作(加减乘除)结束后其他线程就已经可以进入同步块了,以至于造成上述情况:李在进入后执行减操作,之后休眠,同时马进入同样执行减操作后休眠,王重复上述操作,在三者都先后执行完休眠操作,但是此时的number却已经被减了三次了使用呈现上述的删除结果

再做一次实验:

public class MyThread implements  Runnable {
    private static Integer number=10;
    private static Integer number1=10;
    private  boolean flag = true;
    @Override
    public  void run() {
        while (flag) {
            synchronized (number){
                if (number < 1) {
                    flag=false;
                }
                else {
                    System.out.println(Thread.currentThread().getName() + "--number--" +number);
                    number--;
                    System.out.println(Thread.currentThread().getName() + "--number1--" +number1--);
                }
            }
            }
        }

    public static void main(String[] args) {
        MyThread myThread = new MyThread();
        new Thread(myThread,"李").start();
        new Thread(myThread,"马").start();
        new Thread(myThread,"王").start();
    }
}

/*
李--number--10
李--number1--10
李--number--9
李--number1--9
王--number--9
李--number--8
王--number1--8
李--number1--7
马--number--6
王--number--6
马--number1--6
王--number1--5
马--number--4
李--number--4
马--number1--4
李--number1--3
马--number--2
王--number--2
马--number1--2
王--number1--1

可以看到number出现了多次重复,number1却完全没有。可以看出好像只会在操作同步监视器的那一行上锁一样。我以为只有在一个线程执行完同步块后另外一个线程才有机会进入。这是我的一个误区。同步块中最好还是就写相关的操作吧。经过验证Lock锁不存在上述情况

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/195258.html

(0)
小半的头像小半

相关推荐

极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!