上篇介绍了用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. 【LeetCode题意分析&解答】43. Multiply Strings

    Given two numbers represented as strings, return multiplication of the numbers as a string. Note: Th ...

  2. sqlite 查询数据 不用回调

    int main( void ){    sqlite3 *db=NULL;    char *zErrMsg = 0;    int rc;    //打开数据库连接    rc = sqlite3 ...

  3. cpan安装及其使用

    cpan安装及其使用 Perl是一种相当灵活的程序编程语言,现有的许有程序都是使用它进行编程的.它的优点之一就是无需自己编写编码,你就能利用许多增加的模块,创建新的功能. 程序利用这些模块的编码,而程 ...

  4. Using SetWindowRgn

    Using SetWindowRgn Home Back To Tips Page Introduction There are lots of interesting reasons for cre ...

  5. JS 在html中的位置

    前言 当我了解完html在浏览器中的解析渲染流程后,反而又发现了新的困扰自己的问题. Q:即然html要渲染需要渲染树,而渲染树又需要DOMTree和CSSRuleTree,DOMTree需要解析HT ...

  6. SQL函数经常用到的mark一下

    在项目开发过程中存储过程会用到很多SQL函数,经常用到的mark一下 1.经常用到的mark 一下 经常需要把id字符以','分隔传入存储过程然后SQL语句用in去搜索但是经常是这样的情况id 经常是 ...

  7. UVa 11082 Matrix Decompressing(最大流)

    不想吐槽了..sample input 和sample output 完全对不上...调了一个晚上...不想说什么了... -------------------------------------- ...

  8. Java判断字符串是中文还是英文

    在做开发的时候我们经常需要用到根据某个字符或者字符串来判断其是中文还是英文,从而做相应的处理,其实不难,大多数人们都是用到正则来判断的,下面小贝就给大家分享一下Java判断字符串是中文还是英文 推荐文 ...

  9. codility上的练习(5)

    codility出了lesson 5了. (1) 合法括号序列,包括( [ { ) ] }这6种字符的字符串,长度N在[0..200000]范围内,为其是否合法. 要求时间复杂度O(N),空间复杂度O ...

  10. HTML+CSS笔记 CSS进阶

    文字排版 字体 我们可以使用css样式为网页中的文字设置字体.字号.颜色等样式属性. 语法: body{font-family:"宋体";} 这里注意不要设置不常用的字体,因为如果 ...