java-测试synchronized使用xxx.class和this使用的区别
synchronized测试1
写两个线程调用同一个方法,在其中分别做一个class和this的调用,看结果
1.xx.class
public class Test{
public static void main(String[] args) {
System.out.println(new Date().toLocaleString()+";开始创建t1...");
Thread t1 = new Thread(new Runnable() {
public void run() {
new Test().test("t1");
}
});
System.out.println(new Date().toLocaleString()+";开始执行t1...");
t1.start();
System.out.println(new Date().toLocaleString()+";开始创建t2...");
Thread t2 = new Thread(new Runnable() {
public void run() {
new Test().test("t2");
}
});
System.out.println(new Date().toLocaleString()+";开始执行t2...");
t2.start();
}
public void test(String n){
System.out.println(new Date().toLocaleString()+";"+n+"来了");
synchronized (Test.class) {
System.out.println(new Date().toLocaleString()+";"+n+" 我在这里休眠5秒");
try {
Thread.sleep(5*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(new Date().toLocaleString()+";"+n+" 结束");
}
}
打印
2015-10-19 13:56:46;开始创建t1...
2015-10-19 13:56:47;开始执行t1...
2015-10-19 13:56:47;开始创建t2...
2015-10-19 13:56:47;t1来了
2015-10-19 13:56:47;t1 我在这里休眠5秒
2015-10-19 13:56:47;开始执行t2...
2015-10-19 13:56:47;t2来了
2015-10-19 13:56:52;t2 我在这里休眠5秒
2015-10-19 13:56:52;t1 结束
2015-10-19 13:56:57;t2 结束
从打印的结果可以看出,使用class在执行到synchronized时会等待其他占用的线程执行玩才会继续执行
2.对比this
//将上面的案例中的synchronized (Test.class) { 修改成
synchronized (this) {
执行打印输出结果
2015-10-19 14:01:22;开始创建t1...
2015-10-19 14:01:22;开始执行t1...
2015-10-19 14:01:22;开始创建t2...
2015-10-19 14:01:22;t1来了
2015-10-19 14:01:22;开始执行t2...
2015-10-19 14:01:22;t1 我在这里休眠5秒
2015-10-19 14:01:22;t2来了
2015-10-19 14:01:22;t2 我在这里休眠5秒
2015-10-19 14:01:27;t1 结束
2015-10-19 14:01:27;t2 结束
可以看到,使用this执行线程时只会考虑到同一个线程中的同步问题,严格来说是无法达到真正意义上的线程同步
通过调用不同的方法再次测试
首先看使用class代码展示
public class Test{
public static void main(String[] args) {
System.out.println(new Date().toLocaleString()+";开始创建t1...");
Thread t1 = new Thread(new Runnable() {
public void run() {
new Test().test("t1");
}
});
System.out.println(new Date().toLocaleString()+";开始执行t1...");
t1.start();
System.out.println(new Date().toLocaleString()+";开始创建t2...");
Thread t2 = new Thread(new Runnable() {
public void run() {
new Test().test1("t2");
}
});
System.out.println(new Date().toLocaleString()+";开始执行t2...");
t2.start();
}
public void test(String n){
System.out.println(new Date().toLocaleString()+";"+n+"来了");
synchronized (Test.class) {
System.out.println(new Date().toLocaleString()+";"+n+" 我在这里休眠5秒");
try {
Thread.sleep(5*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(new Date().toLocaleString()+";"+n+" 结束");
}
public void test1(String n){
System.out.println(new Date().toLocaleString()+";"+n+"来了");
synchronized (Test.class) {
System.out.println(new Date().toLocaleString()+";"+n+" 我在这里休眠5秒");
try {
Thread.sleep(5*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(new Date().toLocaleString()+";"+n+" 结束");
}
}
执行打印结果
2015-10-19 14:04:58;开始创建t1...
2015-10-19 14:04:58;开始执行t1...
2015-10-19 14:04:58;开始创建t2...
2015-10-19 14:04:58;t1来了
2015-10-19 14:04:58;t1 我在这里休眠5秒
2015-10-19 14:04:58;开始执行t2...
2015-10-19 14:04:58;t2来了
2015-10-19 14:05:03;t2 我在这里休眠5秒
2015-10-19 14:05:03;t1 结束
2015-10-19 14:05:08;t2 结束
通过打印结果可以看到基本与同一个方法执行的结果相同
同样也做this的测试
//将上面的案例中的synchronized (Test.class) { 修改成
synchronized (this) {
打印结果
2015-10-19 14:08:22;开始创建t1...
2015-10-19 14:08:22;开始执行t1...
2015-10-19 14:08:22;开始创建t2...
2015-10-19 14:08:22;t1来了
2015-10-19 14:08:22;t1 我在这里休眠5秒
2015-10-19 14:08:22;开始执行t2...
2015-10-19 14:08:22;t2来了
2015-10-19 14:08:22;t2 我在这里休眠5秒
2015-10-19 14:08:27;t1 结束
2015-10-19 14:08:27;t2 结束
打印结果基本相同
所以得出:在使用线程同步时,处理特殊情况外基本应该使用class
测试static中的线程同步
public class Test{
public static void main(String[] args) {
System.out.println(new Date().toLocaleString()+";开始创建t1...");
Thread t1 = new Thread(new Runnable() {
public void run() {
test("t1");
}
});
System.out.println(new Date().toLocaleString()+";开始执行t1...");
t1.start();
System.out.println(new Date().toLocaleString()+";开始创建t2...");
Thread t2 = new Thread(new Runnable() {
public void run() {
test("t2");
}
});
System.out.println(new Date().toLocaleString()+";开始执行t2...");
t2.start();
}
public static void test(String n){
System.out.println(new Date().toLocaleString()+";"+n+"来了");
synchronized (Test.class) {
System.out.println(new Date().toLocaleString()+";"+n+" 我在这里休眠5秒");
try {
Thread.sleep(5*1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println(new Date().toLocaleString()+";"+n+" 结束");
}
}
打印
2015-10-19 14:10:22;开始创建t1...
2015-10-19 14:10:23;开始执行t1...
2015-10-19 14:10:23;开始创建t2...
2015-10-19 14:10:23;t1来了
2015-10-19 14:10:23;t1 我在这里休眠5秒
2015-10-19 14:10:23;开始执行t2...
2015-10-19 14:10:23;t2来了
2015-10-19 14:10:28;t2 我在这里休眠5秒
2015-10-19 14:10:28;t1 结束
2015-10-19 14:10:33;t2 结束
从结果中可以看出与class执行是一样的,不区分static。
java-测试synchronized使用xxx.class和this使用的区别的更多相关文章
- Java的synchronized的同步代码块和同步方法的区别
synchronized同步方法和同步代码块的区别 同步方法默认使用this或者当前类做为锁. 同步代码块可以选择以什么来加锁,比同步方法更精确,我们可以选择只有会在同步发生同步问题的代码加锁,而并不 ...
- (原)测试 Java中Synchronized锁定对象的用法
今天再android_serial_port中看到了关键字 synchronized;因为刚好在学java和android,所以就查了一下它的用法: 于是把代码中的一小段代码拿了出来,做了一下修改,测 ...
- JAVA多线程synchronized详解
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 当两个并发线程访问同一个对象object中的这个synchronized(this)同 ...
- java.lang.UnsatisfiedLinkError: no XXX in java.library.path
其中涉及的测试源码如下: For those who didn't install Javawith default settings, a systematic way for solving JN ...
- Java锁-Synchronized深层剖析
Java锁-Synchronized深层剖析 前言 Java锁的问题,可以说是每个JavaCoder绕不开的一道坎.如果只是粗浅地了解Synchronized等锁的简单应用,那么就没什么谈的了,也不建 ...
- No.1.测试Synchronized加锁String字符串后的多线程同步状况
测试目的描述 Synchronized关键字锁定String字符串可能会带来严重的后果, 尽量不要使用 synchronized(String a) 因为JVM中,因为字符串常量池具有缓冲功能! 接下 ...
- java 并发——synchronized
java 并发--synchronized 介绍 在平常我们开发的过程中可能会遇到线程安全性的问题,为了保证线程之间操作数据的正确性,我们第一想到的可能就是使用 synchronized 并且 syn ...
- 使用ResponseBodyAdvice统一包装响应返回String的时候出现java.lang.ClassCastException: com.xxx.dto.common.ResponseResult cannot be cast to java.lang.String
代码如下: @Override public ResponseResult<Object> beforeBodyWrite(Object returnValue, MethodParame ...
- Java并发-Synchronized关键字
一.多线程下的i++操作的并发问题 package passtra; public class SynchronizedDemo implements Runnable{ private static ...
随机推荐
- 网页下载Google Play 的App
前言 当你想在google play上下载某个应用,而无奈手机的系统并没有安装google servicess,此刻是否有些捉急? 本文分享的是一个网站,它可以无需手机而直接通过网页下载Google ...
- WEB 业务测试中需要关注的问题
汇总起来分为: 1.浏览器自身的一些操作,后退键,刷新键,样式兼容,多浏览器之间的一些操作 2.键盘快捷键的一些支持 3.所有前端校验,必须也在后端代码进行校验,验证后端是否校验可越过前端校验进 ...
- nginx作为负载均衡服务器——测试
i. 需求 nginx作为负载均衡服务器,用户请求先到达nginx,再由nginx根据负载配置将请求转发至 tomcat服务器. nginx负载均衡服务器:192.168.101.3 tomcat1服 ...
- PAT 1012. 数字分类 (20)
给定一系列正整数,请按要求对数字进行分类,并输出以下5个数字: A1 = 能被5整除的数字中所有偶数的和: A2 = 将被5除后余1的数字按给出顺序进行交错求和,即计算n1-n2+n3-n4...: ...
- 两个经典的Oracle触发器示例(轉)
[案例一] 题目:--触发器:--添加员工信息,流水号作为自动编号(通过序列生成),--并且判断如果工资小于0,则改为0;如果大于10000,则改为10000. CREATE TABLE emp2(e ...
- 路由系统的核心对象——Router
路由系统的核心对象--Router ASP.NET Core应用中的路由机制实现在RouterMiddleware中间件中,它的目的在于通过路由解析为请求找到一个匹配的处理器,同时将请求携带的数据以路 ...
- SQL server 数据库备份还原Sql
/************ 一.数据库备份 ************/ --完整备份默认追加到现有的文件 backup database DBXS To disk='d:\backup\DBXS_fu ...
- DispatcherHelper
DispatcherHelper 通常,WPF 应用程序从两个线程开始:一个用于处理呈现, 一个用于管理 UI.呈现线程有效地隐藏在后台运行,而 UI 线程则接收输入.处理事件.绘制屏幕 以及运行应用 ...
- Theano2.1.7-基础知识之设置的配置和编译模式
来自:http://deeplearning.net/software/theano/tutorial/modes.html Configuration Settings and Compiling ...
- 让你彻底理解 “==”与 Equals
相信很多朋友在面对,对象判等时经常会犹豫是用“==”还是Equals呢?有时候发现两者得到的结果相同,但有时候有不同, 究竟在什么情况下"==" 会相等,什么情况下Equals会不 ...