同步机制实现多线程有序访问资源

2015-07-27 07:38江西信息应用职业技术学院计算机技术系南昌330043
山东工业技术 2015年19期
关键词:同步线程资源

薛 岚(江西信息应用职业技术学院 计算机技术系,南昌 330043)

同步机制实现多线程有序访问资源

薛岚
(江西信息应用职业技术学院计算机技术系,南昌330043)

摘要:当多个线程竞争访问同一个资源时,Java提供了线程同步这种机制来协调各个线程的访问。由于线程同步的复杂性,很多时候开发人员弄不清楚资源是什么、线程何时处于竞争状态,线程同步如何使用等问题,本文将对线程同步问题做深入探讨。

关键词:线程;同步;资源;锁

1 什么是线程同步

多线程是指在同一个程序中同时存在几个执行体,按几条不同的执行路径共同工作的情况。Java允许多线程并发控制,当多个线程访问同一资源时,也就是多个线程同时竞争一个资源同时操作一个可共享的资源变量时(如数据的增删改查),将会导致数据不准确,相互之间产生冲突,如果协调不好就会出现数据不一致的问题。因此当多个线程访问同一资源时,因此加入同步锁让某一个线程独占此资源,也就是锁定该资源,其它线程在此时此刻不能访问该资源,以避免在该线程没有完成操作之前,被其他线程的调用,称为线程同步。从而保证了该变量的唯一性和准确性。

2 线程同步代码表示

在Java代码中运用线程同步机制,有两个关键处的代码需要完成:1、当多个线程竞争访问同一个对象或同一变量时,该对象或变量为竞争资源标识为private;2、当某一个方法或某一段代码在某一个时刻只能被一个线程独自访问,用synchronized关键字标识方法或代码为同步。synchronized只能标记非抽象的方法,不能标识成员变量。

3 同步方式

(1)synchronized方法。用synchronized关键字修饰一个方法,该方法为同步方法。Java中的每个对象资源都有一个锁,或者叫做监视器,当一个线程访问某个对象的同步方法时,该对象被锁住,其他任何线程无法去访问该对象的同步方法了,相当于对象被一个线程独占。直到该线程线程执行方法完毕后(或者是抛出了异常),才将该对象解锁,释放对象资源,其他线程才有可能再去访问该对象的同步方法。

用同步方法实现类成员变量的访问:Java系统为每个类实例都配了一把锁,当要用类实例来调用同步方法时需要获得这个类实例的锁才能执行,此时进入线程运行状态,否则就为线程阻塞。

同步方法一旦被执行执行,其它类实例将无法访问,直到同步方法返回释放锁,其它类实例才有可能访问此方法。被阻塞的其它线程才能获得该锁,重新进入可执行状态。这种机制保证了类中所有同步成员方法在同一时刻只有一个可被类实例访问,因为只有获得了类实例对应的锁的同步成员方法才能被访问,从而有效避免了类成员方法的访问矛盾。在Java中,除了类实例以外,每一个类也对应一把锁,因此也可将类的静态成员方法声明为同步,以避免对类的静态成员的访问冲突。

同步方法的缺点:有些方法若声明为同步将会很大程度地降低执行效率,线程类的run()方法不能声明为同步,否则它对本类中的任何同步方法的调用都不会成功。同步机制需要占用大量内存,而且如果使用不当易造成死锁。

(2)synchronized块。将需要被线程独占访问的代码用大括号括起来前面标识为synchronized,则系统自动为该段语句块加上内置锁,从而构成同步代码块。

同步代码块中的代码必须获得类对象或类的锁才能被线程访问执行。由于任何代码块都可以标识为同步,并且可获得任意对象上的锁,所以同步代码块运用方便灵活。

(3)使用特殊域变量实现线程同步。1).volatile关键字为域变量的访问提供了一种免锁机制;2).使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新;3).因此每次使用该域就要重新计算,而不是使用寄存器中的值;4).volatile不会提供任何原子操作,它也不能用来修饰final类型的变量

(4)使用重入锁实现线程同步。可重入的互斥锁具有与使用同步方法和语句所访问的隐式监视器锁相同的一些基本行为和语义,但功能更强大。它由最近成功获得锁,并且还没有释放该锁的线程拥有。

(5)使用局部变量实现线程同步

4 同步的特点

(1)无论方法还是代码标识为同步,锁住的资源是指对象,而且只要不是多个线程同时访问同步方法和代码块,其还可以被其他线程的对象访问,。

(2)每个对象只对应一个锁,即一个对象只与一个锁相关联。

(3)使用同步机制时需要谨慎,能不用同步实现的操作就不用同步实现。因为使用同步需要占用很大的系统内存,开销很大就有可能造成死锁。

(4)当两个线程同时抢占同一个对象中的同步方法或变量时,只能有一个线程可以执行访问同步方法或变量。另一个线程进入暂时等待状态必须等待当前线程执行完才能访问。

(5)当一个线程访问对象中的一个同步代码块时,这个对象中的其它同步代码块也会被锁住,也就是对其它线程关闭。

(6)当一个线程访问对象的一个同步代码块时,该对象中的非同步方法或变量不受影响,可以被其它线程访问。

(7)当一个线程访问一个对象的某个同步代码块时,该对象的对象锁就自动赋给了此线程。即此线程独占该对象的所有同步方法和变量,禁止同一时刻其它线程对该对象上任何同步方法和变量的访问。

5 线程同步小结

(1)线程同步机制是为了防止多个线程竞争同一资源时由于没协调好而出现线程对资源数据修改的不一致。

(2)线程同步机制需要通过锁来实现,每个对象都有一把锁。当一个线程获得了一个对象上的锁,其它线程在同一时刻就不能访问该对象上的所有同步方法和同步变量

(3)对于静态同步方法,锁是针对这个类的,锁对象是该类的Class对象。静态和非静态方法的锁互不干预。一个线程获得锁,在一个同步方法中访问另一个对象上的同步方法时,会获取这两个对象锁。

(4)使用同步时,要注意在是哪个对象上同步,否则会出现对象不一致。

(5)当多个线程竞争一个资源时,只有获得对象锁的线程才能访问资源,没有获取对象锁的线程将处于暂时阻塞状态。

(6)死锁是多个线程需要获得其它线程占有的资源后才能完成操作,而每个线程又都不肯释放自己占有的资源,造成永远相互等待。

参考文献:

[1]张荣海.Java多线程同步方法的研究[J].黑龙江科技信息,2003 (05).

作者简介:薛岚(1980-),女,江西南昌人,硕士,讲师,研究方向:软件技术专业Java方向。

猜你喜欢
同步线程资源
5G终端模拟系统随机接入过程的设计与实现
实时操作系统mbedOS 互斥量调度机制剖析
浅析体育赛事售票系统错票问题的对策研究
基础教育资源展示
我给资源分分类
资源回收
做好绿色资源保护和开发
素质教育理念下艺术教育改革的思路
政府职能的转变与中国经济结构调整的同步
公共艺术与城市设计的协调与同步