上篇介绍了用synchronized修饰static方式来实现“Class 锁”,今天要介绍另一种实现方式,synchronized(class)代码块,写法不一样但是作用是一样的。下面我附上一段代码来看一下synchronized(class)代码块的基本用法,如下:

public static void main(String[] args) {

		Service4 s1 = new Service4();
Service4 s2 = new Service4();
ThreadA a = new ThreadA(s1);
ThreadB b = new ThreadB(s2);
a.setName("A");
b.setName("B");
a.start();
b.start();
} public static class ThreadA extends Thread { private Service4 service; public ThreadA(Service4 service) {
super();
this.service = service;
} @Override
public void run() { super.run();
service.printA();
}
} public static class ThreadB extends Thread { private Service4 service; public ThreadB(Service4 service) {
super();
this.service = service;
} @Override
public void run() { super.run();
service.printB();
}
} } class Service4 { static public void printA() {
synchronized (Service4.class) {
try {
System.out.println("线程:" + Thread.currentThread().getName()
+ "在" + System.currentTimeMillis() + "进入printA");
Thread.sleep(3000);
System.out.println("线程:" + Thread.currentThread().getName()
+ "在" + System.currentTimeMillis() + "离开printA");
} catch (InterruptedException e) { e.printStackTrace();
}
} } static public void printB() {
synchronized (Service4.class) {
System.out.println("线程:" + Thread.currentThread().getName() + "在"
+ System.currentTimeMillis() + "进入printB");
try {
Thread.sleep(3000);
} catch (InterruptedException e) { e.printStackTrace();
}
System.out.println("线程:" + Thread.currentThread().getName() + "在"
+ System.currentTimeMillis() + "离开printB");
}
} }

      运行结果如下:synchronized(class)代码块的作用和synchronized static的作用是一样的

       以前我说过,synchronized还可以传入其他的实例对象或者方法的形参,那么我现在要说一种把synchronized(class)和String一起使用的特殊情况,还是用代码讲解,下面我附上一段代码,如下:  
	public static void main(String[] args) {

		Service5 service = new Service5();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
} public static class ThreadB extends Thread {
private Service5 service; public ThreadB(Service5 service) {
super();
this.service = service;
} @Override
public void run() {
// TODO Auto-generated method stub
super.run();
service.print("AA");
}
} public static class ThreadA extends Thread {
private Service5 service; public ThreadA(Service5 service) {
super();
this.service = service;
} @Override
public void run() {
// TODO Auto-generated method stub
super.run();
service.print("AA");
}
}
} class Service5 {
public static void print(String string) { try {
synchronized (string) {
while (true) { System.out.println(Thread.currentThread().getName());
Thread.sleep(1000);
}
} } catch (InterruptedException e) { e.printStackTrace();
} }
}
   运行结果如下:可以看到输出结果会打印出无数个连续的A,这是由于在JVM中有String常量池缓存的功能,所以说printA()和printB()两个方法里传进来的“AA”是同一个值,因此两个线程持有相同的锁,所以总有一个线程执行不到。

     

上面已经看到了常量池带来的问题,因此大多情况下,都不用String最为对像锁,而改用其他的,比如new Object()实例化一个Object对象。可以看看下面的例子,运行后的区别在哪,如下:

	public static void main(String[] args) {

		Service6 service = new Service6();
ThreadA a = new ThreadA(service);
a.setName("A");
a.start();
ThreadB b = new ThreadB(service);
b.setName("B");
b.start();
} public static class ThreadB extends Thread {
private Service6 service; public ThreadB(Service6 service) {
super();
this.service = service;
} @Override
public void run() {
// TODO Auto-generated method stub
super.run();
service.print(new Object());
}
} public static class ThreadA extends Thread {
private Service6 service; public ThreadA(Service6 service) {
super();
this.service = service;
} @Override
public void run() {
// TODO Auto-generated method stub
super.run();
service.print(new Object());
}
}
} class Service6 { public static void print(Object object) { try {
synchronized (object) {
while (true) { System.out.println(Thread.currentThread().getName());
Thread.sleep(1000);
}
} } catch (InterruptedException e) { e.printStackTrace();
} }
}

      运行结果如下:可以看到运行结果是交叉的异步的,说明两个线程持有的锁不是同一把锁。

        

Java多线程之synchronized(五)的更多相关文章

  1. JAVA多线程之Synchronized关键字--对象锁的特点

    一,介绍 本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点. 所谓对象锁,就是就是synchronized 给某个对象 加锁.关于 对象锁 可参考:这篇文章 二,分析 s ...

  2. (二)java多线程之synchronized

    本人邮箱: kco1989@qq.com 欢迎转载,转载请注明网址 http://blog.csdn.net/tianshi_kco github: https://github.com/kco198 ...

  3. JAVA多线程之Synchronized、wait、notify实例讲解

    一.Synchronized synchronized中文解释是同步,那么什么是同步呢,解释就是程序中用于控制不同线程间操作发生相对顺序的机制,通俗来讲就是2点,第一要有多线程,第二当多个线程同时竞争 ...

  4. Java多线程之synchronized(四)

    前面几章都是在说synchronized用于对象锁,无论是修饰方法也好修饰代码块也好,然而关键字synchronized还可以应用到static静态方法上,如果这样写,那就是对当前的*.java文件所 ...

  5. Java多线程之synchronized(三)

    在多线程访问同一个对象中的不同的synchronized方法或synchronized代码块的前提下,也就是“对象监控器”为同一个对象的时候,也就是synchronized的锁为同一把锁的时候,调用的 ...

  6. Java多线程之synchronized及其优化

    Synchronized和同步阻塞synchronized是jvm提供的同步和锁机制,与之对应的是jdk层面的J.U.C提供的基于AbstractQueuedSynchronizer的并发组件.syn ...

  7. JAVA多线程之synchronized和volatile实例讲解

    在多线程中,提到线程安全.线程同步,我们经常会想到两个关键字:volatile和synchronized,那么这两者有什么区别呢? 1. volatile修饰的变量具有可见性 volatile是变量修 ...

  8. java 多线程之synchronized wait/notify解决买票问题

    一.Java线程具有五中基本状态 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread(); 就绪状态(Runnable):当调用线程对象的st ...

  9. Java多线程之synchronized和volatile

    概述 用Java来开发多线程程序变得越来越常见,虽然Java提供了并发包来简化多线程程序的编写,但是我们有必要深入研究一下,才能更好的掌握这块知识. 本文主要对Java提供的底层原语synchroni ...

随机推荐

  1. JS表格排序

    var employees = [] employees[0] = { name: "George", age: 32, retiredate: "March 12, 2 ...

  2. Radio Checkbox Select 操作

    一个小总结 <!DOCTYPE html> <html> <head> <meta name="description" content= ...

  3. 关于mysqli 连接数不能正确释放的解决方案

    /** * 析构函数 */ //解决重复链接的问题 private $db_handler = null; function __destruct() { Log::logWrite($this-&g ...

  4. UIWindow 详解

    UIWindow对象是所有UIView的根视图,管理和协调的应用程序的显示.分发事件给View.UIWindow类是UIView的子类,可以看作是特殊的UIView.一般应用程序只有一个UIWindo ...

  5. 精通 VC++ 实效编程280例 - 01 窗口

    窗口是屏幕上的一个矩形区域.窗口分为3种:重叠窗口.弹出窗口和子窗口.每个窗口都有由系统绘制的“非客户区”和应用程序绘制的“客户区”.在 MFC 中,CWnd 类为各种窗口提供了基类. 1 通过 HW ...

  6. Android 新兴的UI模式——侧边导航栏【转】

    侧边导航栏也就是大家熟知的SliddingMenu,英文也叫Fly-In App Menu.Side Navigation等.当然谷歌现在已经推出类似这个效果的组件--Navigation Drawe ...

  7. [cocos2dx笔记015]关于cocos2dx Button三种状态说明

    经过几天的填坑,最终将现有的项目由cocos2dx 2.2.2移到cocos2dx 3.2,差点放弃3.2了,但在最后一刻,又把坑填平了. cocos2dx 2.x到3.x是一个巨大的变化,能够算是全 ...

  8. 虎记:强大的nth-child(n)伪类选择器玩法

    写在前面的戏: 最近参加了度娘前端IFE的春季班,刷任务,百度真是有营销头脑,让咱们这帮未来的技术狂人为他到处打广告(我可不去哪),其中做的几个任务中有几个以前没有用到的东西, 也算是有些许收获(现在 ...

  9. [Jobdu] 题目1517:链表中倒数第k个结点

    给出一个链表的头指针,要求找到倒数第k个节点,并输出这个节点的值 例子: 先看一个例子,链表为:1 2 3 4 5 6,倒数第2个节点就是5,倒数第一个节点就是6,以此类推.这里的链表有头节点,就是说 ...

  10. js函数变量

    局部 JavaScript 变量 在 JavaScript 函数内部声明的变量(使用 var)是局部变量,所以只能在函数内部访问它.(该变量的作用域是局部的). 您可以在不同的函数中使用名称相同的局部 ...