背景:大家都知道用synchronized来实现加锁,使得不会出现线程安全问题。
但是今天在研究一段经典的面试题时(2个线程++,2个线程--)的问题时,发现在一个类的2个方法上全加上synchronized时,所有的线程竟然变得串行了。
因此,研究了一下,发现原来是对象锁的原因,在方法上加上synchronized时,其实默认是占得了此对象的对象锁,而此对象锁是一个对象只有一把钥匙,因此当调用其中一个带synchronized的方法时,其余的线程都拿不到钥匙而只能等待。
其中的一个反例就是,给此对象再加个方法,前面不带synchronized,就会发现,此方法不受对象锁的控制而随机出现,并非串行。
关键代码如下:
int i=0; int k=0; //带synchronized public synchronized void count(){ for(int j=0;j<10;j++){ i++; System.out.println(Thread.currentThread().getName()+"^_^count,i的值为"+i); } } //不带synchronized public void countForFree(){ for(int j=0;j<10;j++){ k++; System.out.println(Thread.currentThread().getName()+"^_^countForFree^_^,k的值为"+k); } } /** * 1、用4个线程,分别访问2个带锁的方法,发现线程全部顺序执行,因为虽然是2个带锁的方法,但是对象锁的钥匙只有一把。 * 2、用2个线程,一个是访问有锁的方法,一个是访问无锁的方法,可以惊人的发现,线程又开始无序执行,说明无锁的方法不受对象锁的控制。 * @param args */ public static void main(String[] args) { SynchronizedTest synchronizedTest=new SynchronizedTest(); new Thread(new MyThread(synchronizedTest)).start(); /*new Thread(new MyThread(synchronizedTest)).start(); new Thread(new MyThread(synchronizedTest)).start(); new Thread(new MyThread(synchronizedTest)).start();*/ new Thread(new FreeThread(synchronizedTest)).start(); }
完整代码:git@git.oschina.net:iPhone2020/MultiThread.git
synchronized对象锁比喻成房子的钥匙的形象比喻:http://www.cnblogs.com/GnagWang/archive/2011/02/27/1966606.html
官方参考链接:https://docs.oracle.com/javase/tutorial/essential/concurrency/syncmeth.html
相关推荐
Java中的同步锁,即`synchronized`关键字,是Java多线程编程中用于解决并发问题的重要机制。它确保了对共享资源的互斥访问,防止数据的不一致性。当我们有多线程环境并涉及到共享数据时,可能会出现竞态条件,就像...
这种机制在Java中被称为互斥锁,可以防止多个线程同时访问同一块代码,确保了线程的串行化执行。 接下来,我们来看看synchronized的两种主要用法:synchronized方法和synchronized块。synchronized方法是通过在方法...
Java并发之串行线程池实例解析 Java并发之串行线程池实例解析是Java并发编程中非常重要的一部分,今天我们就来详细介绍如何实现一个串行的线程池实例。在介绍之前,首先我们需要了解什么是串行线程池。串行线程池是...
这里提到的"Synchronized原理.jpg"可能是一份关于Java同步机制的资料。在Java中,`synchronized`关键字用于控制多线程对共享资源的访问,确保同一时间只有一个线程可以执行特定代码块。这主要涉及到Java内存模型...
Java串口程序源码是一种基于Java语言实现的通信程序,它允许通过计算机的串行端口(Serial Port)进行数据的发送和接收。在嵌入式系统、工业控制、物联网设备等场景中,串口通信扮演着重要的角色,因为它是简单、...
Java串行通信是指Java程序通过串行端口(通常是RS232)与其他设备进行数据交换的过程。在Java中实现串行通信通常需要借助于`comm.jar`库,这是Sun公司提供的一个标准扩展库。该库包含了多个类和接口,用于简化串行...
Java还提供了一些同步机制,如 `synchronized` 关键字、`wait()`, `notify()` 和 `notifyAll()` 方法,以及 `java.util.concurrent` 包中的高级并发工具。 ```java class MyRunnable implements Runnable { public...
Java的串行通信API,如`javax.comm`,会被讲解。同时,数据可视化工具,如JFreeChart,用于创建温度变化的图表,帮助理解数据趋势。 5. 类和对象:Java是一种面向对象的语言,课程会强调封装、继承和多态三大特性。...
6. **Stream API**:Java 8引入的Stream API提供了处理集合的新方式,支持串行和并行操作,极大地提高了代码的可读性和性能。 7. **日期与时间API**:Java 8对日期和时间API进行了重大改进,引入了java.time包,...
10. **并行与串行压缩老年代收集**:Java 8对老年代的垃圾收集进行了优化,提供了并行和串行两种压缩模式,以适应不同场景的需求。 深入学习JVM不仅能够帮助我们编写更高效的Java代码,还能让我们在遇到性能问题时...
线程同步是解决多线程共享资源问题的关键,Java提供了synchronized关键字、wait()、notify()和notifyAll()等机制来实现。 Socket通信是网络编程的基础,TCP是面向连接的、可靠的协议,UDP是无连接的、不可靠的。...
1. **`java.comm`包**:Java标准版(Java SE)提供了一个`java.comm`包,包含了`SerialPort`、`CommPortIdentifier`等类,用于处理串行通信。然而,这个包在Java 6之后就不再更新,且只支持Windows系统,对于Linux等...
源码中包含了`java.lang.Thread`类和相关的同步机制,如`synchronized`关键字、`java.util.concurrent`包中的并发工具类。这些可以帮助你深入理解并发编程的底层实现。 5. **异常处理**:Java的异常处理机制在`java...
7. **垃圾收集**:Java的自动内存管理依赖于垃圾收集,书中会讨论不同类型的垃圾收集器,如串行、并行、CMS和G1,并讲解如何优化垃圾收集策略。 8. **JVM内部**:这部分深入解析JVM的工作原理,包括类加载、字节码...
书中会详细讲解不同类型的垃圾收集器,如串行、并行、CMS和G1,以及如何选择和调整合适的GC策略以减少停顿时间。 2. **JVM调优**:了解JVM的工作原理是优化性能的基础。书中会涵盖JVM的类加载机制、内存模型(堆、...
10. **并发编程**:Java提供了丰富的并发工具类,如ExecutorService、Semaphore、CountDownLatch等,以及synchronized关键字和 volatile 变量,帮助开发者编写高效的多线程程序。 在实际开发中,查阅JDK API文档...
总结一下,Java线程同步通过`synchronized`关键字提供了线程安全的共享资源访问。同步方法和同步代码块是实现同步的两种主要方式,它们都基于监视器(锁)的概念,确保在任何时刻只有一个线程能执行特定的代码段。在...
Java语言提供了volatile 和synchronized 两个关键字来保证线程之间操作的有序性,volatile 是因为其本身包含“禁止指令重排序”的语义,synchronized是由“一个变量在同一个时刻只允许一条线程对其进行lock 操作”这...
流可以操作集合、数组,甚至I/O通道,支持串行和并行操作,常用的方法有`filter()`、`map()`、`reduce()`等。 6. **异常处理(Exception Handling)** - Java通过`try-catch-finally`语句块进行异常处理。`try`块中...
4. **垃圾收集**:Java SE 7的垃圾收集器有多种,如串行、并行、并发和G1等。它们通过标记-清除、复制、标记-整理和分代等算法来回收内存。垃圾收集是Java程序员无需手动管理的重要特性,有助于编写更简洁、更健壮的...