Java多线程之synchronized(五)
上篇介绍了用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(五)的更多相关文章
- JAVA多线程之Synchronized关键字--对象锁的特点
一,介绍 本文介绍JAVA多线程中的synchronized关键字作为对象锁的一些知识点. 所谓对象锁,就是就是synchronized 给某个对象 加锁.关于 对象锁 可参考:这篇文章 二,分析 s ...
- (二)java多线程之synchronized
本人邮箱: kco1989@qq.com 欢迎转载,转载请注明网址 http://blog.csdn.net/tianshi_kco github: https://github.com/kco198 ...
- JAVA多线程之Synchronized、wait、notify实例讲解
一.Synchronized synchronized中文解释是同步,那么什么是同步呢,解释就是程序中用于控制不同线程间操作发生相对顺序的机制,通俗来讲就是2点,第一要有多线程,第二当多个线程同时竞争 ...
- Java多线程之synchronized(四)
前面几章都是在说synchronized用于对象锁,无论是修饰方法也好修饰代码块也好,然而关键字synchronized还可以应用到static静态方法上,如果这样写,那就是对当前的*.java文件所 ...
- Java多线程之synchronized(三)
在多线程访问同一个对象中的不同的synchronized方法或synchronized代码块的前提下,也就是“对象监控器”为同一个对象的时候,也就是synchronized的锁为同一把锁的时候,调用的 ...
- Java多线程之synchronized及其优化
Synchronized和同步阻塞synchronized是jvm提供的同步和锁机制,与之对应的是jdk层面的J.U.C提供的基于AbstractQueuedSynchronizer的并发组件.syn ...
- JAVA多线程之synchronized和volatile实例讲解
在多线程中,提到线程安全.线程同步,我们经常会想到两个关键字:volatile和synchronized,那么这两者有什么区别呢? 1. volatile修饰的变量具有可见性 volatile是变量修 ...
- java 多线程之synchronized wait/notify解决买票问题
一.Java线程具有五中基本状态 新建状态(New):当线程对象对创建后,即进入了新建状态,如:Thread t = new MyThread(); 就绪状态(Runnable):当调用线程对象的st ...
- Java多线程之synchronized和volatile
概述 用Java来开发多线程程序变得越来越常见,虽然Java提供了并发包来简化多线程程序的编写,但是我们有必要深入研究一下,才能更好的掌握这块知识. 本文主要对Java提供的底层原语synchroni ...
随机推荐
- java Socket 列子 一些参数设置比较全
http://blog.csdn.net/a19881029/article/details/11596945
- 一維條碼 EAN13 的編碼方式
何謂 EAN-13碼 ? ▲ 國家代號(3位數) 中華民國的國家代號為471. ▲ 廠商代號(6位數) 由本會核發給廠商6位數的廠商代號. ▲ 商品代號(3位數) 由廠商自行編定,按一物一號的原則,不 ...
- Bootstrap禁用响应式布局
在Bootstrap中极其重要的一个技术内容便是响应式布局了,一次编码针对不同设备终端的强大能力使得响应式技术愈发流行. 不过正所谓"萝卜青菜各有所爱",如果你想要使用Bootst ...
- Netty那点事: 概述, Netty中的buffer, Channel与Pipeline
Netty那点事(一)概述 Netty和Mina是Java世界非常知名的通讯框架.它们都出自同一个作者,Mina诞生略早,属于Apache基金会,而Netty开始在Jboss名下,后来出来自立门户ne ...
- BZOJ 1037 [ZJOI2008]生日聚会Party(单调DP)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1037 [题目大意] 现在有n个男生,m个女生排成一行,要求不存在一个区间男女之差大于k ...
- Yet Another Multiple Problem(bfs好题)
Yet Another Multiple Problem Time Limit : 40000/20000ms (Java/Other) Memory Limit : 65536/65536K ( ...
- #308 (div.2) A. Vanya and Table
1.题目描写叙述:点击打开链接 2.解题思路:本题是一道简单的模拟题.每次扫描一个输入的长方形,然后将内部全部点都+1,终于统计数组全部元素的和就可以. 3.代码: #define _CRT_SECU ...
- 通过jstack定位在线执行java系统故障_案例1
问题描写叙述: 在一个在线执行的java web系统中,会定时执行一个FTP上传的任务,结果有一天发现,文件正常生成后却没有上传. 问题初步分析: 1.查看日志文件 发现这个任务仅仅打印了開始进入FT ...
- (译)Node.js的 EventEmitter 教程
原文标题:Node.js EventEmitter Tutorial 原文链接:http://www.hacksparrow.com/node-js-eventemitter-tutorial.htm ...
- Jquery开发插件的方法
Jquery未开发插件提供了两个方法: (1)Jquery.extend(object) -为Jquery类本身添加新的方法;代码如下: $.extend({ add:function(a,b) ...