Java多线程同步问题的探究(二、给我一把锁,我能创造一个规矩)

在上一篇中,我们讲到了多线程是如何处理共享资源的,以及保证他们对资源进行互斥访问所依赖的重要机制:对象锁。

本篇中,我们来看一看传统的同步实现方式以及这背后的原理。

很多人都知道,在Java多线程编程中,有一个重要的关键字,synchronized。但是很多人看到这个东西会感到困惑:“都说同步机制是 通过对象锁来实现的,但是这么一个关键字,我也看不出来Java程序锁住了哪个对象阿?“

没错,我一开始也是对这个问题感到困惑和不解。不过还好,我们有下面的这个例程:

1 public class ThreadTest extends Thread {
2
3     private int threadNo;
4
5      public ThreadTest(int threadNo) {
6         this.threadNo = threadNo;
7     }
8
9      public static void main(String[] args) throws Exception {
10         for (int i = 1; i <  10; i++) {
11             new ThreadTest(i).start();
12             Thread.sleep (1);
13         }
14     }
15
16     @Override
17     public synchronized void  run() {
18         for (int i = 1; i < 10000; i++) {
19              System.out.println("No." + threadNo + ":" + i);
20         }
21     }
22 }

这个程序其实就是让10个线程在控制台上数数,从1数到9999。理想情况下,我们希望看到一个线程数完,然后才是另一个线程开始数 数。但是这个程序的执行过程告诉我们,这些线程还是乱糟糟的在那里抢着报数,丝毫没有任何规矩可言。

但是细心的读者注意到:run方法还是加了一个synchronized关键字的,按道理说,这些线程应该可以一个接一个的执行这个run方法才 对阿。

但是通过上一篇中,我们提到的,对于一个成员方法加synchronized关键字,这实际上是以这个成员方法所在的对象本身作为对象锁。 在本例中,就是以ThreadTest类的一个具体对象,也就是该线程自身作为对象锁的。一共十个线程,每个线程持有自己线程对象的那个对 象锁。这必然不能产生同步的效果。换句话说,如果要对这些线程进行同步,那么这些线程所持有的对象锁应当是共享且唯一的!

时间: 2024-09-30 18:23:45

Java多线程同步问题的探究(二、给我一把锁,我能创造一个规矩)的相关文章

Java多线程同步问题的探究(一、线程的先来后到)

众所周知,在Java多线程编程中,一个非常重要的方面就是线程的同步问题. 关于线程的同步,一般有以下解决方法: 1. 在需要同步的方法的方法签名中加入synchronized关键字. 2. 使用synchronized块对需要进行同步的代码段进行同步. 3. 使用JDK 5中提供的java.util.concurrent.lock包中的Lock对象. 另外,为了解决多个线程对同一变量进行访问时可能发生的安全性问题,我们不仅可以采用同步机制,更可以通过JDK 1.2中加入的 ThreadLocal

Java多线程同步问题的探究(三、Lock来了,大家都让开【1.认识重入锁】)

在上一节中,我们已经了解了Java多线程编程中常用的关键字synchronized,以及与之相关的对象锁机制.这一节中,让我们一起来认 识JDK 5中新引入的并发框架中的锁机制. 我想很多购买了<Java程序员面试宝典>之类图书的朋友一定对下面这个面试题感到非常熟悉: 问:请对比synchronized与java.util.concurrent.locks.Lock 的异同. 答案:主要相同点:Lock能完成synchronized所实现的所有功能 主要不同点:Lock有比synchroniz

Java多线程同步问题的探究(四)

四.协作,互斥下的协作--Java多线程协作(wait.notify.notifyAll) Java监视器支持两种线程:互斥和协作. 前面我们介绍了采用对象锁和重入锁来实现的互斥.这一篇中,我们来看一看线程的协作. 举个例子:有一家汉堡店举办吃汉堡比赛,决赛时有3个顾客来吃,3个厨师来做,一个服务员负责协调汉堡的数量.为了避免浪费,制 作好的汉堡被放进一个能装有10个汉堡的长条状容器中,按照先进先出的原则取汉堡.如果容器被装满,则厨师停止做汉堡,如果顾客发 现容器内的汉堡吃完了,就可以拍响容器上

Java多线程同步问题的探究(五)

五.你有我有全都有-- ThreadLocal如何解决并发安全性? 前面我们介绍了Java当中多个线程抢占一个共享资源的问题.但不论是同步还是重入锁,都不能实实在在的解决资源紧缺的情况,这些 方案只是靠制定规则来约束线程的行为,让它们不再拼命的争抢,而不是真正从实质上解决他们对资源的需求. 在JDK 1.2当中,引入了java.lang.ThreadLocal.它为我们提供了一种全新的思路来解决线程并发的问题.但是他的名字难免让我们望 文生义:本地线程? 什么是本地线程? 本地线程开玩笑的说:不

Java 多线程同步问题的探究(三、Lock来了,大家都让开【2】)

[2. Fair or Unfair It is a question...] 让我们继续前面有关ReentrantLock的话题. 首先,ReentrantLock有一个带布尔型参数的构造函数,在JDK官方文档中对它是这样描 述的: "此类的构造方法接受一个可选的公平 参数.当设置为 true 时,在多个线程的争用下,这些锁倾向于将访问权授予等待时间 最长的线程.否则此锁将无法保证任何特定访问顺序.与采用默认设置(使用不公平锁)相比,使用公平锁的程序在许多线程访问时表现 为很低的总体吞吐量(即

java多线程同步的问题

问题描述 java多线程同步的问题 小测试,如何实现变量ticket的同步 private int ticket = 100; public void run() { while(ticket > 0 ) { System.out.println(ticket+" is saled by "+ Thread.currentThread().getName()); ticket--; try { Thread.sleep(200); } catch (InterruptedExce

java多线程同步问题,小弟百撕不得其解,特来求助!

问题描述 java多线程同步问题,小弟百撕不得其解,特来求助! 多线程共享同一资源,同一张票卖出了多张!同步方法,同步代码块都没用. 问题:编写三各类Ticket.SealWindow.TicketSealCenter分别代表票信息.售票窗口.售票中心.售票中心分配一定数量的票,由若干个售票窗口进行出售,利用你所学的线程知识来模拟此售票过程. public class ThreadDemo { public static void main(String[] args) { Thread t1

ava 同步-Java 多线程同步工具 CyclicBarrier

问题描述 Java 多线程同步工具 CyclicBarrier Java中使用CyclicBarrier控制多个线程在执行完后,才执行后续操作,请大家帮我分析下,项目两个代码中为什么执行结果不一样: 代码1. public class CyclicBarrierTest2 { public static void main(String[] args) throws InterruptedException, BrokenBarrierException { final CyclicBarrie

java多线程-同步块实例讲解_java

java多线程-同步块 Java 同步块(synchronized block)用来标记方法或者代码块是同步的.Java 同步块用来避免竞争.本文介绍以下内容: Java 同步关键字(synchronzied) 实例方法同步 静态方法同步 实例方法中同步块 静态方法中同步块 Java 同步示例 Java 同步关键字(synchronized) Java 中的同步块用 synchronized 标记.同步块在 Java 中是同步在某个对象上.所有同步在一个对象上的同步块在同时只能被一个线程进入并执