您当前的位置:首页 > 互联网教程

java中的synchronized()的具体作用

发布时间:2025-05-25 12:40:29    发布人:远客网络

java中的synchronized()的具体作用

一、java中的synchronized()的具体作用

1、在多线程编程中,多个线程可能同时访问同一数据对象,从而导致数据访问冲突。Java语言为此提供了解决方案,即synchronized关键字。synchronized关键字有两种用法:synchronized方法和synchronized块。

2、synchronized方法是通过在方法声明中加入synchronized关键字来实现的。例如:public synchronized void accessVal(int newVal);这种方法能够控制对类成员变量的访问,每个类实例对应一把锁。当一个线程调用该方法时,它必须获得该类实例的锁。如果已经有一个线程拥有该锁,调用线程将被阻塞,直到锁被释放。这种机制确保了同一时刻对于每个类实例,其所有声明为synchronized的方法中至多只有一个处于可执行状态,从而避免了类成员变量的访问冲突。

3、除了synchronized方法,Java还提供了synchronized块。synchronized块的语法如下:synchronized(syncObject){//允许访问控制的代码}其中的代码必须获得对象syncObject的锁才能执行。这个对象可以是类实例或类。synchronized块提供了更灵活的锁定机制,可以根据需要锁定任意代码块和任意对象。

4、需要注意的是,将大方法声明为synchronized可能会严重影响效率。例如,如果将线程类的方法run()声明为synchronized,由于线程在整个生命期内都在运行,所以它对本类任何synchronized方法的调用将永远不会成功。为了克服这个问题,可以将访问类成员变量的代码封装到一个专门的方法中,并将其声明为synchronized,在主方法中调用。不过,Java提供了更好的解决方案,即synchronized块。

5、总之,掌握synchronized关键字的应用可以有效避免多线程编程中的数据访问冲突。对于初学者来说,建议搭建好开发环境,多编写代码,实际操作有助于更好地理解synchronized关键字的用法。尽管网上有很多资料,但亲自实践往往能发现更多有趣的细节。

二、java多线程中synchronized关键字的用法

1、由于同一进程内的多个线程共享内存空间在Java中就是共享实例当多个线程试图同时修改某个实例的内容时就会造成冲突因此线程必须实现共享互斥使多线程同步

2、最简单的同步是将一个方法标记为synchronized对同一个实例来说任一时刻只能有一个synchronized方法在执行当一个方法正在执行某个synchronized方法时其他线程如果想要执行这个实例的任意一个synchronized方法都必须等待当前执行 synchronized方法的线程退出此方法后才能依次执行

3、但是非synchronized方法不受影响不管当前有没有执行synchronized方法非synchronized方法都可以被多个线程同时执行

4、此外必须注意只有同一实例的synchronized方法同一时间只能被一个线程执行不同实例的synchronized方法是可以并发的例如 class A定义了synchronized方法sync()则不同实例a sync()和a sync()可以同时由两个线程来执行

5、多线程同步的实现最终依赖锁机制我们可以想象某一共享资源是一间屋子每个人都是一个线程当A希望进入房间时他必须获得门锁一旦A获得门锁他进去后就立刻将门锁上于是B C D就不得不在门外等待直到A释放锁出来后 B C D中的某一人抢到了该锁(具体抢法依赖于 JVM的实现可以先到先得也可以随机挑选)然后进屋又将门锁上这样任一时刻最多有一人在屋内(使用共享资源)

6、 Java语言规范内置了对多线程的支持对于Java程序来说每一个对象实例都有一把锁一旦某个线程获得了该锁别的线程如果希望获得该锁只能等待这个线程释放锁之后获得锁的方法只有一个就是synchronized关键字例如

7、 public int getCount(){ return count;}

8、 public synchronized void setCount(int count){ unt= count;}

9、同步方法public synchronized void setCount(int count){ unt= count;}事实上相当于

10、 public void setCount(int count){

11、 synchronized(this){//在此获得this锁

12、红色部分表示需要同步的代码段该区域为危险区域如果两个以上的线程同时执行会引发冲突因此要更改SharedResource的内部状态必须先获得SharedResource实例的锁

13、退出synchronized块时线程拥有的锁自动释放于是别的线程又可以获取该锁了

14、为了提高性能不一定要锁定this例如 SharedResource有两个独立变化的变量

15、 public synchronized void setA(int a){ this a= a;}

16、 public synchronized void setB(int b){ this b= b;}

17、若同步整个方法则setA()的时候无法setB() setB()时无法setA()为了提高性能可以使用不同对象的锁

18、 private Object sync_a= new Object()

19、 private Object sync_b= new Object()

20、 public synchronized void setB(int b){

三、Java 如何同步顺序执行多个线程

这个要分段来实现,第一步是让线程同步,第二部是让线程有顺序。

同步:我们可以用synchronized来解决。

Java线程同步原理: java会为每个object对象分配一个monitor,当某个对象的同步方法(synchronized methods)被多个线程调用时,该对象的monitor将负责处理这些访问的并发独占要求。

当一个线程调用一个对象的同步方法时,JVM会检查该对象的monitor。如果monitor没有被占用,那么这个线程就得到了monitor的占有权,可以继续执行该对象的同步方法;如果monitor被其他线程所占用,那么该线程将被挂起,直到monitor被释放。

当线程退出同步方法调用时,该线程会释放monitor,这将允许其他等待的线程获得monitor以使对同步方法的调用执行下去。就像下面这样:

//这里只会有一个线程来调用该方法,因为只有一个this对象作为资源分配给该线程

顺序:我们可以用List来解决,因为它是有序的。我们只需要将要执行的线程放入到List中

*让多个线程同步顺序执行的线程管理器

*待执行的线程集合,注意这里必须是Runnable接口类型,下面会解释

private List<Runnable> runnableList;

public SyncManager(List<Runnable> runnableList){

this.runnableList= runnableList;

public void setRunnable(List<Runnable> runnableList){

this.runnableList= runnableList;

for(Runnable runnable: runnableList){

private void runThread(Runnable runnable){

runnable.run();//这里需要注意的是:必须调用run方法,因为如果你调用了start方法,线程只会向JVM请求资源,但是未必就执行其中的run。

//这个方法是同步的,所以当前只有一个线程占用了this对象。