Java多线程之synchronized关键词(Demo详解)

简介: 你好我是辰兮,很高兴你能来阅读,本篇文章为大家讲解Java多线程之synchronized关键词,下面有案例的截图和相关代码可以自行实践,相关的更多面试知识已经提前整理好文章可以阅读学习,分享获取新知,希望对Java初学者有帮助。

@[toc]


一、序言

多线程访问临界资源时的数据安全问题

产生原因:有多个线程在同时访问一个资源,如果一个线程在取值的过程中,时间片又被其他线程抢走了,临界资源问题就产生了


how to解决临界资源问题

解决方案:一个线程在访问临界资源的时候,如果给这个资源“上一把锁”,这个时候如果其他线程也要访问这个资源, 就得在“锁”外面等待


对象锁:任意的对象都可以被当做锁来使用
类锁:把一个类当做锁,语法为:类名.class


同步代码块

语法:
synchronized(锁) { 
//需要访问临界资源的代码段 
}

说明:

  • a.程序走到代码段中,就用锁来锁住了临界资源,这个时候,其他线程不能执行代码段中的代码,只能在锁外边等待
  • b.执行完代码段中的这段代码,会自动解锁。然后剩下的其他线程开始争抢cpu时间片
  • c.一定要保证不同的线程看到的是同一把锁,否则同步代码块没有意义.

synchronized是Java中的关键字,是一种同步锁。它修饰的对象有以下几种:

  1. 修饰一个代码块,被修饰的代码块称为同步语句块,其作用的范围是大括号{}括起来的代码,作用的对象是调用这个代码块的对象;
  2. 修饰一个方法,被修饰的方法称为同步方法,其作用的范围是整个方法,作用的对象是调用这个方法的对象;
  3. 修改一个静态的方法,其作用的范围是整个静态方法,作用的对象是这个类的所有对象;
  4. 修改一个类,其作用的范围是synchronized后面括号括起来的部分,作用主的对象是这个类的所有对象。

在这里插入图片描述


二、同步代码块和对象锁的使用

在这里插入图片描述

在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行。

同步代码块结合对象锁

在这里插入图片描述

  • 参考代码如下,大家自行运行实践(ps:可以去除 synchronized关键字)
package demo1;

public class SellTickets {
    static int count = 10;

    //任何对象都可以充当一个对象锁
    static Object obj = new Object();
    static Runnable r = new Runnable() {
      @Override
      public void run() {
          while(count > 0) {
              System.out.println(Thread.currentThread().getName()+"--");
              synchronized(obj){
                  count--;
                  if(count <= 0) {
                      return;
                  }
                  System.out.println(Thread.currentThread().getName() + "售出了 一张票,剩余" + count);
                  
              }
          }
      }
  };
    public static void main(String[] args) {
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        Thread t3 = new Thread(r);
       // t1.setPriority(8);
        t1.start();
        t2.start();
        t3.start();
      }
}

三、同步代码块和类锁的使用

  • 使用类锁的案例如下,参考格式 即 类.class

在这里插入图片描述


四、 同步方法

  • 首先给大家展示没有加锁的方法

在这里插入图片描述

  • 然后再给大家展示加锁的方法

在这里插入图片描述

  • 参考代码如下,大家自行运行实践(ps:可以去除 synchronized关键字)
package demo1;

public class SellTickets {
    static int count = 100;
    //任何对象都可以充当一个对象锁
    //static Object obj = new Object();
    static Runnable r = new Runnable() {
      @Override
      public void run() {
          while(count > 0) {
           sellTickets();
          }
      }
        //同步方法,作用和同步代码块一样
        public synchronized void sellTickets() {
            if (count <= 0) {
                return;
            }
            count--;
            System.out.println("售票员" + Thread.currentThread().getName() + "售出一张票,余额 为" + count);
        }
    };
    public static void main(String[] args) {
        Thread t1 = new Thread(r);
        Thread t2 = new Thread(r);
        Thread t3 = new Thread(r);
       // t1.setPriority(8);
        t1.start();
        t2.start();
        t3.start();
      }
}

The best investment is to invest in yourself

目录
相关文章
|
6天前
|
存储 缓存 安全
【Java面试题汇总】多线程、JUC、锁篇(2023版)
线程和进程的区别、CAS的ABA问题、AQS、哪些地方使用了CAS、怎么保证线程安全、线程同步方式、synchronized的用法及原理、Lock、volatile、线程的六个状态、ThreadLocal、线程通信方式、创建方式、两种创建线程池的方法、线程池设置合适的线程数、线程安全的集合?ConcurrentHashMap、JUC
【Java面试题汇总】多线程、JUC、锁篇(2023版)
|
2天前
|
Java
深入理解Java中的多线程编程
本文将探讨Java多线程编程的核心概念和技术,包括线程的创建与管理、同步机制以及并发工具类的应用。我们将通过实例分析,帮助读者更好地理解和应用Java多线程编程,提高程序的性能和响应能力。
15 4
|
10天前
|
Java 调度 开发者
Java并发编程:深入理解线程池
在Java的世界中,线程池是提升应用性能、实现高效并发处理的关键工具。本文将深入浅出地介绍线程池的核心概念、工作原理以及如何在实际应用中有效利用线程池来优化资源管理和任务调度。通过本文的学习,读者能够掌握线程池的基本使用技巧,并理解其背后的设计哲学。
|
1天前
|
安全 Java 调度
Java 并发编程中的线程安全和性能优化
本文将深入探讨Java并发编程中的关键概念,包括线程安全、同步机制以及性能优化。我们将从基础入手,逐步解析高级技术,并通过实例展示如何在实际开发中应用这些知识。阅读完本文后,读者将对如何在多线程环境中编写高效且安全的Java代码有一个全面的了解。
|
10天前
|
缓存 监控 Java
Java中的并发编程:理解并应用线程池
在Java的并发编程中,线程池是提高应用程序性能的关键工具。本文将深入探讨如何有效利用线程池来管理资源、提升效率和简化代码结构。我们将从基础概念出发,逐步介绍线程池的配置、使用场景以及最佳实践,帮助开发者更好地掌握并发编程的核心技巧。
|
9天前
|
存储 安全 Java
Java并发编程之深入理解Synchronized关键字
在Java的并发编程领域,synchronized关键字扮演着守护者的角色。它确保了多个线程访问共享资源时的同步性和安全性。本文将通过浅显易懂的语言和实例,带你一步步了解synchronized的神秘面纱,从基本使用到底层原理,再到它的优化技巧,让你在编写高效安全的多线程代码时更加得心应手。
|
6天前
|
Java 调度 开发者
Java中的多线程基础及其应用
【9月更文挑战第13天】本文将深入探讨Java中的多线程概念,从基本理论到实际应用,带你一步步了解如何有效使用多线程来提升程序的性能。我们将通过实际代码示例,展示如何在Java中创建和管理线程,以及如何利用线程池优化资源管理。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧,帮助你更好地理解和应用多线程编程。
|
10天前
|
安全 Java UED
Java并发编程:解锁多线程的潜力
在Java的世界里,并发编程如同一场精心编排的交响乐,每个线程扮演着不同的乐手,共同奏响性能与效率的和声。本文将引导你走进Java并发编程的大门,探索如何在多核处理器上优雅地舞动多线程,从而提升应用的性能和响应性。我们将从基础概念出发,逐步深入到高级技巧,让你的代码在并行处理的海洋中乘风破浪。
|
2月前
|
存储 安全 Java
Java面试题:请解释Java内存模型,并说明如何在多线程环境下使用synchronized关键字实现同步,阐述ConcurrentHashMap与HashMap的区别,以及它如何在并发环境中提高性能
Java面试题:请解释Java内存模型,并说明如何在多线程环境下使用synchronized关键字实现同步,阐述ConcurrentHashMap与HashMap的区别,以及它如何在并发环境中提高性能
26 0
|
2月前
|
安全 Java 开发者
Java多线程:synchronized关键字和ReentrantLock的区别,为什么我们可能需要使用ReentrantLock而不是synchronized?
Java多线程:synchronized关键字和ReentrantLock的区别,为什么我们可能需要使用ReentrantLock而不是synchronized?
36 0