Java多线程(二) synchronized 针对对象进行锁定
2024-09-30 18:49:03
http://www.cnblogs.com/QQParadise/articles/5059824.html
1.方法内的变量为线程安全的
2.实例变量非线程安全的
public class HasSelfPrivateNum { private int num = 0;
synchronized public void addI(String username) {
try { if (username.equals("a")) {
System.out.println("a set over");
num = 100;
Thread.sleep(2000);
}else{
num =200;
System.out.println("b set over");
}
System.out.println(username+" num="+num);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
ThreadA
public class ThreadA extends Thread{ private HasSelfPrivateNum numRef; public ThreadA(HasSelfPrivateNum numRef){
this.numRef =numRef;
} public void run(){
numRef.addI("a");
}
}
ThreadB
public class ThreadB extends Thread{ private HasSelfPrivateNum numRef; public ThreadB(HasSelfPrivateNum numRef){
this.numRef =numRef;
} public void run(){
numRef.addI("b");
}
}
Run
public class RunDemo { public static void main(String[] args) { HasSelfPrivateNum numRef = new HasSelfPrivateNum(); HasSelfPrivateNum numRef2 = new HasSelfPrivateNum();
ThreadA athread = new ThreadA(numRef);
athread.start(); ThreadB bthread = new ThreadB(numRef2);
bthread.start(); }
}
例子不会发生脏读,因为是不同的对象
非线程安全其实会在多线程对同一个对象中的实例变量进行并发访问时发生,
产生的后果就是“脏读”,也就是取到的数据其实是被更改过的。
1)调用关键字synchronized声明的方法一定是排队运行的。只有共享资源的读写访问才需要同步化,如果不是共享资源,那么根本就没有同步的必要。
2)synchronized 同步块
不在synchronized块中就是异步执行,在synchronized块中就是同步执行
3)多个线程调用一个对象中的不同名称的synchronized同步方法或synchronized(this) 同步代码块时,调用的效果就是按顺序执行,也就是同步的,阻塞的。
4) 锁非this 对象具有一定的优点:如果在一个类中有很多个synchronized方法,这时
虽然能实现同步,但会受到阻塞,所以影响运行效率;但如果使用同步代码块锁非
this对象,则synchronized(this) 代码块中的程序与同步方法是异步的,不与其他锁this同步方法争抢this锁,则可以大大提高运行效率。
4.volatile 强制性从公共堆栈中进行取值,增加了实例变量在多个线程之间的可见性
public class Run { public static void main(String[] args) throws InterruptedException {
Task task = new Task();
ThreadA threadA = new ThreadA(task);
threadA.setName("A");
threadA.start();
Thread.sleep(100);
ThreadB threadB = new ThreadB(task);
threadB.setName("B");
threadB.start();
}
}
public class Task { synchronized public void otherMethod() {
System.out.println("-----------run othermethod");
} synchronized public void doLongTimeTask() {
for (int i = 0; i < 100; i++) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println("syn threadName=" + Thread.currentThread().getName() + "i=" + (i + 1));
}
}
}
public class ThreadA extends Thread { private Task task; public ThreadA(Task task){
this.task =task;
}
public void run(){
task.doLongTimeTask();
}
} public class ThreadB extends Thread { private Task task; public ThreadB(Task task){
this.task =task;
}
public void run(){
task.otherMethod();
}
}
最新文章
- 【webapp的优化整理】要做移动前端优化的朋友进来看看吧
- IOS 7 风格Checkbox
- ajax基本用法
- linux中查看硬件温度的命令
- SpringDataMongoDB介绍(一)-入门
- oj 小黑熊偷玉米
- Apache指南:CGI动态页面
- 关于 DropDownList 循环绑定中遇到的问题
- PHP Xdebug安装及配置
- Android 开发工具类 19_NetworkStateReceiver
- loadrunner使用https请求
- numpy的基础运算2-【老鱼学numpy】
- php扩展打开不起作用的原因, php数字显示2147483647的原因
- cocos开发插件笔记
- win10更新后 chrome内核浏览器总是打开网页一直加载 甚至打不开 解决方法
- [hgoi#2019/2/24]玄学考试
- 【转】STM32 - 程序跳转、中断、开关总中断
- ThinkPHP 模型方法 setInc() 和 setDec() 使用详解
- 第一章 第一个dubbo项目
- MFC各种属性定义及DLL使用理解