Java多线程synchronized同步
非线程安全问题
“非线程安全”问题存在于“实例变量”中,如果是方法内部的私有变量,则不存在“非线程问题”。也即是说,方法中的变量永远是线程安全的。
如果多个线程共同访问1个对象中的实例变量,则可能线程不安全。下面以实例说明
public class HasSelfNum {
private int num = 0;
public void add(String name) {
try {
if (name.equals("a")) {
num = 100;
System.out.println("a over");
Thread.sleep(1000);
} else {
num = 200;
System.out.println("b over");
}
System.out.println(name+" "+num);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class ThreadA extends Thread{
private HasSelfNum hasSelfNum;
public ThreadA(HasSelfNum hasSelfNum) {
this.hasSelfNum = hasSelfNum;
}
@Override
public void run() {
super.run();
hasSelfNum.add("a");
}
}
public class ThreadB extends Thread{
private HasSelfNum hasSelfNum;
public ThreadB(HasSelfNum hasSelfNum) {
this.hasSelfNum = hasSelfNum;
}
@Override
public void run() {
super.run();
hasSelfNum.add("b");
}
}
public class Main {
public static void main(String[] args) {
HasSelfNum hasSelfNum = new HasSelfNum();
ThreadA threadA = new ThreadA(hasSelfNum);
ThreadB threadB = new ThreadB(hasSelfNum);
threadA.start();
threadB.start();
}
}
Result
a over
b over
b 200
a 200
a over
a 100
b over
b 200
线程安全,同步访问add()方法
如果是多个对象的情况?
将上面的Main.java进行修改
public class Main {
public static void main(String[] args) {
HasSelfNum hasSelfNum = new HasSelfNum();
HasSelfNum hasSelfNum2 = new HasSelfNum(); //两个对象
ThreadA threadA = new ThreadA(hasSelfNum);
ThreadB threadB = new ThreadB(hasSelfNum2);
threadA.start();
threadB.start();
}
}
Result
a over
b over
b 200
a 100
若类中既有synchronized类型方法又有非synchronized类型方法
public class MyObject {
synchronized public void methodA(){
try {
System.out.println(Thread.currentThread().getName()+" begin");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+" end");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void methodB(){
try {
System.out.println(Thread.currentThread().getName()+" begin");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName()+" end");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
public class ThreadA extends Thread{
MyObject myObject;
public ThreadA(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
super.run();
myObject.methodA();
}
}
public class ThreadB extends Thread{
MyObject myObject;
public ThreadB(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
super.run();
myObject.methodB();
}
}
public class Main {
public static void main(String[] args) {
MyObject myObject = new MyObject();
ThreadA threadA = new ThreadA(myObject);
ThreadB threadB = new ThreadB(myObject);
threadA.setName("A");
threadB.setName("B");
threadA.start();
threadB.start();
}
}
Result
A begin
B begin
B end
A end
A begin
A end
B begin
B end
线程A、B以同步的方式执行对象中的两方法
synchronized同步代码块
public class MyObject {
synchronized public void methodA() {
try {
System.out.println(Thread.currentThread().getName() + " begin");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " end");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public void methodB(MyObject myObject) {
synchronized (myObject) {
try {
System.out.println(Thread.currentThread().getName() + " begin");
Thread.sleep(1000);
System.out.println(Thread.currentThread().getName() + " end");
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
public class ThreadA extends Thread{
MyObject myObject;
public ThreadA(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
super.run();
myObject.methodA();
}
}
public class ThreadB extends Thread{
MyObject myObject;
public ThreadB(MyObject myObject) {
this.myObject = myObject;
}
@Override
public void run() {
super.run();
myObject.methodB(myObject);
}
}
public class Main {
public static void main(String[] args) {
MyObject myObject = new MyObject();
ThreadA threadA = new ThreadA(myObject);
ThreadB threadB = new ThreadB(myObject);
threadA.setName("A");
threadB.setName("B");
threadB.start();
threadA.start();
}
}
Result
B begin
B end
A begin
A end
《Java多线程编程核心技术》学习
Java多线程synchronized同步的更多相关文章
- Java 多线程 —— synchronized关键字
java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...
- Java多线程的同步控制记录
Java多线程的同步控制记录 一.重入锁 重入锁完全可以代替 synchronized 关键字.在JDK 1.5 早期版本,重入锁的性能优于 synchronized.JDK 1.6 开始,对于 sy ...
- Java多线程之同步集合和并发集合
Java多线程之同步集合和并发集合 不管是同步集合还是并发集合他们都支持线程安全,他们之间主要的区别体现在性能和可扩展性,还有他们如何实现的线程安全. 同步集合类 Hashtable Vector 同 ...
- Java多线程编程(同步、死锁、生产消费者问题)
Java多线程编程(同步.死锁.生产消费): 关于线程同步以及死锁问题: 线程同步概念:是指若干个线程对象并行进行资源的访问时实现的资源处理保护操作: 线程死锁概念:是指两个线程都在等待对方先完成,造 ...
- Java多线程的同步机制(synchronized)
一段synchronized的代码被一个线程执行之前,他要先拿到执行这段代码的权限,在 java里边就是拿到某个同步对象的锁(一个对象只有一把锁): 如果这个时候同步对象的锁被其他线程拿走了,他(这个 ...
- JAVA多线程synchronized详解
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码. 当两个并发线程访问同一个对象object中的这个synchronized(this)同 ...
- 转载:浅谈Java多线程的同步问题【很好我就留下来,多分共享】
转载:http://www.cnblogs.com/phinecos/archive/2010/03/13/1684877.html#undefined 多线程的同步依靠的是对象锁机制,synchro ...
- 浅谈Java多线程的同步问题 【转】
多线程的同步依靠的是对象锁机制,synchronized关键字的背后就是利用了封锁来实现对共享资源的互斥访问. 下面以一个简单的实例来进行对比分析.实例要完成的工作非常简单,就是创建10个线程,每个线 ...
- Java多线程 - 线程同步
多线程操作同一个对象时,容易引发线程安全问题.为了解决线程安全问题,Java多线程引入了同步监视器. 同步代码块 同步代码块语法格式如下: synchronized(obj){ //此处的代码即为同步 ...
随机推荐
- 如何将动态生成Word文件
大致的思路是先用office2003或者2007编辑好Word的样式,然后另存为XML,将XML翻译为FreeMarker模板,最后用Java来解析FreeMarker模板并输出Doc.经测试这样方式 ...
- React Native填坑之旅--组件生命周期
这次我们来填React Native生命周期的坑.这一点非常重要,需要有一个清晰的认识.如果你了解Android或者iOS的话,你会非常熟悉我们今天要说的的内容. 基本上一个React Native的 ...
- UVALive 4329 Ping pong(树状数组)
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=13895 题意:一条街上住有n个乒乓选手,每个人都有一个技能值,现在 ...
- C# 以附加文件方式连接SQL Server数据库文件
string str = @"data source=.\SQLEXPRESS;Integrated Security=SSPI;AttachDBFileName=z:\ttt.mdf;Us ...
- 举例详解CSS中的cursor属性
这篇文章主要举例介绍了CSS中的cursor属性,包括zoom-in/zoom-out和grab/grabbing等常用属性值的使用,需要的朋友可以参考下 一.开篇之言 CSS3的领域范围已经渗透到了 ...
- 我的Sharepoint视图的使用
视图是个很灵活的工具,不过在使用前,为了更好的管理视图,我会将Contribute的权限的视图功能去掉. 普通用户都设为Contribute权限,有增删改操作就行. 这样做主要有三个目的: 1.不能让 ...
- 查找当前目录和所有子目录下的后缀名为.o的文件,删除之
查找: find . -name "*.o" -exec ls {} \; 删除: find . -name "*.o" -exec rm -f {} \;
- 用户图形界面(GUI)学习笔记(一)——Swing与AWT
一.Swing与AWT 对象窗口工具箱(Abstact Window Toolkit,AWT),是JAVA1.0刚出现的时候,包含的一个GUI设计类库.它将处理用户界面元素的任务委派给每个目标平台(W ...
- centos7 zabbix3 install done
centOS7安装zabbix3.0 一.前提: 现在zabbix出现了3.0版本,服务器端只支持centOS7,客户端和代理可以支持centOS6,实验环境是服务端安装centOS7,客户用cent ...
- 新版SDWebImage的使用
第一步,下载SDWebImage,导入工程.github托管地址https://github.com/rs/SDWebImage 第二步,在需要的地方导入头文件 1 #import "UII ...