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

目录
相关文章
|
4天前
|
安全 Java UED
Java中的多线程编程:从基础到实践
本文深入探讨了Java中的多线程编程,包括线程的创建、生命周期管理以及同步机制。通过实例展示了如何使用Thread类和Runnable接口来创建线程,讨论了线程安全问题及解决策略,如使用synchronized关键字和ReentrantLock类。文章还涵盖了线程间通信的方式,包括wait()、notify()和notifyAll()方法,以及如何避免死锁。此外,还介绍了高级并发工具如CountDownLatch和CyclicBarrier的使用方法。通过综合运用这些技术,可以有效提高多线程程序的性能和可靠性。
|
4天前
|
缓存 Java UED
Java中的多线程编程:从基础到实践
【10月更文挑战第13天】 Java作为一门跨平台的编程语言,其强大的多线程能力一直是其核心优势之一。本文将从最基础的概念讲起,逐步深入探讨Java多线程的实现方式及其应用场景,通过实例讲解帮助读者更好地理解和应用这一技术。
22 3
|
8天前
|
Java 调度 UED
深入理解Java中的多线程与并发机制
本文将详细探讨Java中多线程的概念、实现方式及并发机制,包括线程的生命周期、同步与锁机制以及高级并发工具。通过实例代码演示,帮助读者理解如何在Java中有效地处理多线程和并发问题,提高程序的性能和响应能力。
|
6天前
|
缓存 安全 Java
使用 Java 内存模型解决多线程中的数据竞争问题
【10月更文挑战第11天】在 Java 多线程编程中,数据竞争是一个常见问题。通过使用 `synchronized` 关键字、`volatile` 关键字、原子类、显式锁、避免共享可变数据、合理设计数据结构、遵循线程安全原则和使用线程池等方法,可以有效解决数据竞争问题,确保程序的正确性和稳定性。
13 2
|
7天前
|
存储 安全 Java
Java-如何保证线程安全?
【10月更文挑战第10天】
|
8天前
|
Java
|
8天前
|
Java
让星星⭐月亮告诉你,Java synchronized(*.class) synchronized 方法 synchronized(this)分析
本文通过Java代码示例,介绍了`synchronized`关键字在类和实例方法上的使用。总结了三种情况:1) 类级别的锁,多个实例对象在同一时刻只能有一个获取锁;2) 实例方法级别的锁,多个实例对象可以同时执行;3) 同一实例对象的多个线程,同一时刻只能有一个线程执行同步方法。
9 1
|
8天前
|
Java
【编程进阶知识】揭秘Java多线程:并发与顺序编程的奥秘
本文介绍了Java多线程编程的基础,通过对比顺序执行和并发执行的方式,展示了如何使用`run`方法和`start`方法来控制线程的执行模式。文章通过具体示例详细解析了两者的异同及应用场景,帮助读者更好地理解和运用多线程技术。
21 1
|
2天前
|
缓存 算法 Java
Java 中线程和纤程Fiber的区别是什么?
【10月更文挑战第14天】
10 0
|
7天前
|
安全 Java 开发者
java的synchronized有几种加锁方式
Java的 `synchronized`通过上述三种加锁方式,为开发者提供了从粗粒度到细粒度的并发控制能力,满足了不同场景下的线程安全需求。合理选择加锁方式对于提升程序的并发性能和正确性至关重要,开发者应根据实际应用场景的特性和性能要求来决定使用哪种加锁策略。
9 0