码迷,mamicode.com
首页 > 其他好文 > 详细

同步方法

时间:2020-04-29 18:54:55      阅读:68      评论:0      收藏:0      [点我收藏+]

标签:没有   run   静态方法   err   this   ted   ima   分析   被锁   

public class SellTickets implements Runnable{
    //共有100张票
    private int tickets = 100;
    private Object obj = new Object();
    private int x = 0;

    @Override
    public void run() {
        while (true) {
            //锁多条语句操作共享数据,当线程1运行进入锁时,对外相当于被锁起来,其他线程只能等待线程1运行结束才能进入。
            if (x % 2 == 0) {
                synchronized (obj) {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                        tickets--;
                    }
                }
            } else {
                synchronized (obj) {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                        tickets--;
                    }
                }
            }
            x++;
        }
    }
}

将上述代码中else部分使用一个单独的方法并加锁来实现:

private synchronized void SellTicket() {
if (tickets > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
tickets--;
}
}

此时来运行卖票测试类:

技术图片此时仍然会发生数据安全问题,原因在于synchronized关键字在锁方法时,锁的是一个方法,其对应的对象应该能表示本方法的——this,而在if中锁的对象仍然还是Object,所以会发生问题,将if语句中锁的对象修改为this后的代码:

synchronized (this) {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                        tickets--;
                    }

此时的运行结果:

技术图片没有出现数据安全问题

那么如果我将synchronized加到静态方法上,锁对应的对象应该是什么?

分析staic关键字可以猜到,锁静态方法时,应该是要锁一个与类相关的对象——类名.class(字节码文件)

技术图片
public class SellTickets implements Runnable{
    //共有100张票
    private static int tickets = 100;
    private Object obj = new Object();
    private int x = 0;

    @Override
    public void run() {
        while (true) {
            //锁多条语句操作共享数据,当线程1运行进入锁时,对外相当于被锁起来,其他线程只能等待线程1运行结束才能进入。
            if (x % 2 == 0) {
                synchronized (SellTickets.class) {
                    if (tickets > 0) {
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
                        tickets--;
                    }
                }
            } else {
                SellTicket();
            }
            x++;
        }
    }

    private static synchronized void SellTicket() {
        if (tickets > 0) {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
            tickets--;
        }
    }
}
View Code

 技术图片运行结果也是没有问题的。

同步方法

标签:没有   run   静态方法   err   this   ted   ima   分析   被锁   

原文地址:https://www.cnblogs.com/pxy-1999/p/12803551.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!