位置:首页 > Java > 同步方法与步骤详解及常见问题指南

同步方法与步骤详解及常见问题指南

时间:2026-08-15  |  作者:清风无痕  |  阅读:0

同步方法的作用

结合前面几个小节的内容不难看出,同步代码块确实能比较直接地解决线程安全问题。只要把对共享资源的操作放进synchronized限定的范围里,这些操作就等于加上了同步锁。

其实,synchronized不只可以写在代码块上,也可以直接放在方法前面进行修饰。一旦方法被这样标记,它就成了同步方法,作用和同步代码块本质上一致。对应的语法格式如下:

[修饰符] synchronized 返回值类型 方法名([参数1,……]){}

被synchronized修饰的方法在某一时刻只允许一个线程访问。

访问该方法的其他线程都会发生阻塞,直到当前线程访问完毕后,其他线程才有机会执行。

同步方法示例:模拟售票系统

接下来使用同步方法模拟售票系统,如文件1所示。

文件1 Example13.ja va

 1    // 定义SaleThread3类实现Runnable接口
 2        class SaleThread3 implements Runnable {
 3        private int tickets = 10;
 4        public void run() {
 5            while (true) {
 6                saleTicket(); // 调用售票方法
 7            }
 8        }
 9        // 定义一个同步方法saleTicket()
 10        private synchronized void saleTicket() {
 11            if (tickets > 0) {
 12                try {
 13                    Thread.sleep(100); // 模拟售票耗时过程
 14                } catch (InterruptedException e) {
 15                    e.printStackTrace();
 16                }
 17                System.out.println(Thread.currentThread().getName() 
 18                                     + " 正在发售第 " + tickets-- + " 张票 ");
 19            }
 20        }
 21    }
 22    public class Example13 {
 23        public static void main(String[] args) {
 24            SaleThread3 saleThread = new SaleThread3(); 
 25            // 创建并开启四个线程,模拟4个售票窗口
 26            new Thread(saleThread, "窗口1").start();
 27            new Thread(saleThread, "窗口2").start();
 28            new Thread(saleThread, "窗口3").start();
 29            new Thread(saleThread, "窗口4").start();
 30        }
 31    }

运行结果如图1所示。

同步方法与步骤详解及常见问题指南_wishdown.com

图1 运行结果

运行结果分析

文件1中,将售票代码抽取为售票方法saleTicket(),并用synchronized关键字把saleTicket()修饰为同步方法,然后在run()方法中调用该方法。

从图1可以看出,同样没有出现0号和负数号的票,说明同步方法实现了和同步代码块一样的效果。

同步方法的锁是什么

很多人都会想到这个问题:既然同步代码块的锁可以是开发者自己指定的任意对象,那么同步方法是不是也有一把“锁”?

有,而且这把锁很明确——就是当前调用这个方法的对象,也就是 this 所指向的那个对象。

这样设计有个很直接的好处:对于所有访问这个方法的线程来说,方法所属的对象是同一个,因此锁天然具备唯一性。

也正因为如此,当某个线程进入这个同步方法之后,其他线程就无法同时进入,必须等到它执行结束、释放锁之后才能继续。线程同步的效果,也正是由此实现的。

静态同步方法的锁

有时候需要同步的方法是静态方法,静态方法不需要创建对象就可以直接用“类名.方法名()”的方式调用。

这时候我们就会有一个疑问,如果不创建对象,静态同步方法的锁就不会是this,那么静态同步方法的锁是什么?

Ja va中静态方法的锁是该方法所在类的class对象,该对象可以直接类名.class的方式获取。

同步机制的优点与弊端

  • 好处:同步解决了多个线程同时访问共享数据时的线程安全问题。
  • 前提:只要加上同一个锁,在同一时间内只能有一条线程执行。
  • 弊端:线程在执行同步代码时每次都会判断锁的状态,非常消耗资源,效率较低。

免责声明:文中图文均来自网络,如有侵权请联系删除,心愿游戏发布此文仅为传递信息,不代表心愿游戏认同其观点或证实其描述。

相关文章

更多

精选合集

更多

大家都在玩

热门话题

大家都在看

更多