synchronized有两种,一种是锁定方法,一种是锁定代码块,区别仅是锁定代码块更加灵活,性能消耗更少。
下面举两个例子,第一个:
public class TestSynchronizedMethod1 implements Runnable{ /** * 当两个并发线程访问同一个对象object中的这个synchronized(this)同步代码块时,一个时间内只能有一个线程得到执行。 * 另一个线程必须等待当前线程执行完这个代码块以后才能执行该代码块。 * @author cdzhujun */ public void run(){ synchronized (this) { for(int i=0;i<5;i++){ System.out.println(Thread.currentThread().getName() + " synchronized loop " + i); } } } public static void main(String[] args) { TestSynchronizedMethod1 t1 = new TestSynchronizedMethod1(); Thread ta = new Thread(t1,"A"); Thread tb = new Thread(t1,"B"); ta.start(); tb.start(); } }
执行结果为:
A synchronized loop 0 A synchronized loop 1 A synchronized loop 2 A synchronized loop 3 A synchronized loop 4 B synchronized loop 0 B synchronized loop 1 B synchronized loop 2 B synchronized loop 3 B synchronized loop 4
以上程序演示了锁的基本作用。
第二个例子:
public class TestSynchronizedMethod2 implements Runnable { /** * 然而,当一个线程访问object的一个synchronized(this)同步代码块时, * 另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。 * @author cdzhujun */ int b = 100; public synchronized void m1() throws Exception { b = 1000; Thread.sleep(5000); System.out.println("b = " + b); } //m2方法可以被主线程调用,变量b作为一个资源仍然可以被访问,synchronized仅锁住的是m1这个方法,并没有锁住b这个变量资源 public void m2() throws Exception { Thread.sleep(2500); b = 2000; } // public void m2() { // System.out.println(b); // } public void run() { try { m1(); } catch (Exception e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { TestSynchronizedMethod2 tsm = new TestSynchronizedMethod2(); Thread t = new Thread(tsm); t.start(); Thread.sleep(1000); tsm.m2(); } }
程序执行结果为:5秒后,输出:b = 2000
第二个例子的解释:main这个主线程调用tsm.m2()这个方法,因m2()是非synchronized方法,故可以访问。所以程序的执行顺序是,tsm启动了一个新线程,等待的5秒过程中,主线程main调用tsm.m2()这个方法,将b设置为2000,然后5秒后m1再输出,此时b已经为2000。(m1里确实设置了b=1000,但2500毫秒后,m2这个方法又重新设置了值)。
这里注意:synchronized锁住的是当前这个对象的所有加锁的方法块和这个对象。
如何理解?就是说:
1、当一个线程访问object的一个synchronized(this)同步代码块时, 另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。
2、不同的对象实例的 synchronized方法是不相干扰的。也就是说,其它线程照样可以同时访问相同类的另一个对象实例中的synchronized方法。
3、其他线程访问该object对象的非synchronized代码块时,对象的成员变量,作为一种资源,仍然可以被访问(第二个例子中的变量b)。
通过以上例子,相信大家对synchronized关键字的理解应该会有一个正确的认识。
相关推荐
### Java线程教程知识点梳理 #### 一、教程概述 - **目标读者**: 本教程主要面向具备丰富Java基础知识但缺乏多线程编程经验的学习者。 - **学习成果**: 学习者能够掌握编写简单的多线程程序的能力,并能够理解和...
"Java多线程-知识点梳理和总结-超详细-面试知识点" Java多线程是Java编程语言中最基本也是最重要的概念之一。多线程编程可以提高程序的执行效率、改善用户体验和提高系统的可扩展性。但是,多线程编程也存在一些...
1. Java线程基础知识 - 线程是程序中独立的、并发的执行路径。每个线程都有自己的堆栈、程序计数器和局部变量,但与分隔的进程不同,线程之间的隔离程度较小,它们共享内存、文件句柄等资源。 - Java语言原生支持...
以下将详细梳理Java多线程编程中的一些关键知识点。 首先,Java多线程实现主要依赖于两个核心接口:`java.lang.Thread`和`java.lang.Runnable`。 1. `java.lang.Thread`是Java中用于表示线程的类。创建线程有两种...
Java多线程是Java开发中的重要组成部分,它允许程序同时执行多个任务,提高了系统的效率和响应性。在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。下面将对Java多线程的相关知识点进行详细的...
### Java多线程知识点总结及企业真题解析 #### 一、知识点总结 ##### (1)多线程相关概念 1. **程序、进程和线程的区分**: - **程序**:为了完成特定的任务而编写的指令集合。它是静态的概念。 - **进程**:...
在Java编程语言中,synchronized关键字扮演着至关重要的角色,它是Java中的同步机制,用于控制多线程对共享资源的访问,以确保数据的一致性和完整性。本篇文章将通过思维导图的形式,深入探讨synchronized的关键概念...
Java提供了丰富的并发工具,如synchronized关键字、volatile变量、Lock接口、ThreadLocal、Future/Tasks等,帮助开发者实现高效的并发控制和通信。理解并发模型和线程安全的概念是每个Java开发者必须掌握的技能。 ...
Java提供了强大的多线程支持,包括Thread类、Runnable接口、ExecutorService、Future、synchronized关键字、Lock接口等。理解和应用并发编程概念,如线程安全、死锁、活锁、线程池管理,是提升系统性能的重要手段。 ...
通过对本书内容的梳理,我们可以发现它涵盖了多个关键的知识点,这些知识点是每一位Java工程师在提升技能、优化实践过程中不可或缺的。 首先,基础语法是Java学习的起点。Java是一种面向对象的语言,因此对类、对象...
Java提供了多种线程同步的方法,如synchronized关键字、显式锁(Lock)以及各种并发集合类。 #### 死锁与活锁 死锁是指两个或两个以上的线程在执行过程中,因争夺资源而造成的一种僵局。而活锁虽然不会阻塞线程,...
- Java多线程编程的基础知识,如创建线程的方式(继承Thread类或实现Runnable接口)、同步机制(synchronized、volatile关键字)。 8. 常用类库 - Java标准库中提供的常用类,例如集合框架(Collection Framework...
以下是根据《Java面试宝典2018版》的内容梳理出的详细知识点: Java基础部分知识点: 1. Java源文件中可以包含多个类,但只有一个公共类(public class)且文件名应与公共类名相同。 2. Java中没有goto语句。 3. ...
在IT领域,多线程是程序设计中的一个重要概念,尤其在服务器端开发、并发处理以及高性能计算中不可或...通过“多线程最全笔记思维导图.xmind”这个文件,你可以系统地梳理和学习多线程的相关知识,形成清晰的理解框架。
Java提供了线程的创建、调度和同步控制机制,如synchronized关键字、锁、条件变量等。 13. Java语言的编译和运行流程:Java程序的开发流程包括源代码编写、编译和运行三个主要步骤。Java源代码文件(.java)通过...
7. **多线程**:Java内置对多线程的支持,学习如何创建和管理线程,理解线程同步和互斥的概念,如synchronized关键字和wait/notify机制。 8. **反射与注解**:反射机制允许程序在运行时动态地获取类的信息并调用其...
Java提供了丰富的多线程并发工具,如Thread、Runnable、synchronized关键字、Lock接口、Future、ExecutorService等,支持线程同步、互斥、协作和异步计算。 **Spring框架原理** Spring是一个全面的后端开发框架,...
- Synchronized和Lock的区别和用法:Synchronized是Java的关键字,提供了内置的同步机制,而Lock是显式的锁机制,提供了更灵活的控制。 - equals()和hashCode()的作用:equals()方法用于判断两个对象是否相等,...
1. 多线程与并发:Java提供了丰富的并发工具类和接口,如ExecutorService、Future、Callable、ThreadLocal等,以及synchronized、volatile关键字,理解它们的工作原理和用法,能有效处理多线程环境下的同步和异步...