Java中synchronized,java当中synchronized的作用

  Java中synchronized,java当中synchronized的作用

  00-1010用法介绍1。修改公共方法2。修改静态方法3。修改代码块摘要在Java语言中,保证线程安全的主要手段是锁,而Java中的锁主要有两种:synchronized和lock。今天,我们将重点介绍synchronized的几种用法。

  00-1010使用synchronized时,不需要手动锁定和释放锁定。我们只需要声明synchronized关键字,JVM级别会自动为我们锁定和释放锁。Synchronized可用于修饰公共方法、静态方法和代码块。我们分开来看。

  

目录

同步修改常用方法的用法如下:

 

  /** * synchronized修改普通方法*/public synchronized void方法(){//.synchronized修改普通方法时,被修改的方法称为synchronous方法,它的作用域是整个方法,代理对象是调用这个方法的对象。

  

用法简介

同步修改静态方法类似于修改普通方法,其用法如下:

 

  /** *同步修饰静态方法*/公共静态同步void静态方法(){//.synchronized修饰静态方法时,它的作用域是整个程序,这个锁对于所有调用这个锁的对象都是互斥的。

  所谓互斥,就是同一时间只能使用一个线程,其他线程只能排队等待。

  普通方法与静态修改方法

  同步修改普通方法和静态方法看似一样,实则完全不同。对于静态方法,同步锁定是全局的,即在整个程序运行过程中,所有调用这个静态方法的对象是互斥的,而普通方法是针对对象级的。不同的对象对应不同的锁,如下面的代码,它调用方法两次,但获取锁的方式完全不同。实现代码如下:

  导入Java . time . local datetime;导入Java . util . concurrent . executorservice;导入Java . util . concurrent . executors;导入Java . util . concurrent . time unit;类同步用法{ public static void main(string[]args)抛出中断异常{//创建线程池并执行任务executorservice thread pool=executors . newfixedthreadpool(10);//执行两次静态方法thread pool . Execute(()-{ static method());});//执行常用方法synchronized usage usage=new synchronized usage()两次;usage . method();synchronized usage usage 2=new synchronized usage();usage 2 . method();} /** * synchronized修改公共方法*该方法的执行需要3s(因为有3s的睡眠时间)*/public synchronized void method(){ system . out . println(公共方法执行时间: local datetime . now());试试{//Hibernate 3s TimeUnit。seconds . sleep;} catch(interrupted exception e){ e . printstacktrace();} * synchronized修改静态方法public Static synchronized void Static method(){ system . out . println(静态方法执行时间: local datetime . now());}上述程序的执行结果如下:

  p style="text-align:center">

  从上述结果可以看出,静态方法加锁是全局的,针对的是所有调用者;而普通方法加锁是对象级别的,不同的对象拥有的锁也不同。

  

 

  

3、修饰代码块

我们在日常开发中,最常用的是给代码块加锁,而不是给方法加锁,因为给方法加锁,相当于给整个方法全部加锁,这样的话锁的粒度就太大了,程序的执行性能就会受到影响,所以通常情况下,我们会使用 synchronized 给代码块加锁,它的实现语法如下:

 

  

public void classMethod() throws InterruptedException { // 前置代码... // 加锁代码 synchronized (SynchronizedUsage.class) { // ...... } // 后置代码...}

从上述代码我们可以看出,相比于修饰方法,修饰代码块需要自己手动指定加锁对象,加锁的对象通常使用 this 或 xxx.class 这样的形式来表示,比如以下代码:

 

  

// 加锁某个类synchronized (SynchronizedUsage.class) { // ......}// 加锁当前类对象synchronized (this) { // ......}

this VS class

 

  使用 synchronized 加锁 this 和 xxx.class 是完全不同的,当加锁 this 时,表示用当前的对象进行加锁,每个对象都对应了一把锁;而当使用 xxx.class 加锁时,表示使用某个类(而非类实例)来加锁,它是应用程序级别的,是全局生效的,如以下代码所示:

  

import java.time.LocalDateTime;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.TimeUnit;public class SynchronizedUsageBlock { public static void main(String[] args) throws InterruptedException { // 创建线程池同时执行任务 ExecutorService threadPool = Executors.newFixedThreadPool(10); // 执行两次 synchronized(this) threadPool.execute(() -> { SynchronizedUsageBlock usage = new SynchronizedUsageBlock(); usage.thisMethod(); }); SynchronizedUsageBlock usage2 = new SynchronizedUsageBlock(); usage2.thisMethod(); // 执行两次 synchronized(xxx.class) SynchronizedUsageBlock usage3 = new SynchronizedUsageBlock(); usage3.classMethod(); SynchronizedUsageBlock usage4 = new SynchronizedUsageBlock(); usage4.classMethod(); } /** * synchronized(this) 加锁 * 本方法的执行需要 3s(因为有 3s 的休眠时间) */ public void thisMethod() { synchronized (this) { System.out.println("synchronized(this) 加锁:" + LocalDateTime.now()); try { // 休眠 3s TimeUnit.SECONDS.sleep(3); } catch (InterruptedException e) { e.printStackTrace(); } } * synchronized(xxx.class) 加锁 public void classMethod() { synchronized (SynchronizedUsageBlock.class) { System.out.println("synchronized(xxx.class) 加锁:" + LocalDateTime.now());}

以上程序的执行结果如下:

 

  

 

  

 

  

总结

synchronized 用 3 种用法,用它可以来修饰普通方法、静态方法和代码块,其中最常用的是修饰代码块,而修饰代码块时需要指定一个加锁对象,这个加锁对象通常使用 this 或 xxx.class 来表示,当使用 this 时,表示使用当前对象来加锁,而使用 class 时,表示表示使用某个类(非类对象实例)来加锁,它是全局生效的。

 

  到此这篇关于Java中synchronized用法汇总的文章就介绍到这了,更多相关java synchronized用法内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: