synchronized锁住的是代码还是jquery对象转html代码

Java多线程之Synchronized关键字--对象锁的特点_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Java多线程之Synchronized关键字--对象锁的特点
来源:Linux社区&
作者:hapjin
本文介绍Java多线程中的synchronized关键字作为对象锁的一些知识点。
所谓对象锁,就是就是synchronized 给某个对象加锁。关于 对象锁 可参考:这篇文章&
synchronized可以修饰实例方法,如下形式:
1 public class MyObject {
synchronized public void methodA() {
//do something....
这里,synchronized 关键字锁住的是当前对象。这也是称为对象锁的原因。
为啥锁住当前对象?因为 methodA()是个实例方法,要想执行methodA(),需要以 对象.方法() 的形式进行调用(obj.methodA(),obj是MyObject类的一个对象,synchronized就是把obj这个对象加锁了)。
上面代码也可写成这样:
1 public class MyObject {
public void methodA() {
synchronized(this){
//do something....
使用synchronized关键字同步一个明显的特点是:MyObject类中定义有多个synchronized修饰的实例方法时,若多个线程拥有同一个MyObject类的对象,则这些方法只能以同步的方式执行。即,执行完一个synchronized修饰的方法后,才能执行另一个synchronized修饰的方法。
1 public class MyObject {
synchronized public void methodA() {
//do something....
synchronized public void methodB() {
//do some other thing
MyObject类中有两个synchronized修饰的方法。
1 public class ThreadA extends Thread {
private MyO
4 //省略构造方法
public void run() {
super.run();
object.methodA();
线程A执行methodA()
public class ThreadB extends Thread {
private MyO
//省略构造方法
public void run() {
super.run();
object.methodB();
线程B执行methodB()
public class Run {
public static void main(String[] args) {
MyObject object = new MyObject();
//线程A与线程B 持有的是同一个对象:object
ThreadA a = new ThreadA(object);
ThreadB b = new ThreadB(object);
a.start();
b.start();
由于线程A和线程B持有同一个MyObject类的对象object,尽管这两个线程需要调用不同的方法,但是必须是同步的,比如:线程B需要等待线程A执行完了methodA()方法之后,它才能执行methodB()方法。
从上可以看出,本文中讲述的 synchronized 锁的范围是整个对象。如果一个类中有多个synchronized修饰的同步方法,且多个线程持有该类的同一个对象(该类的相同的对象),尽管它们调用不同的方法,各个方法的执行也是同步的。
如果各个同步的方法之间没有共享变量,或者说各个方法之间没有联系,但也只能同步执行,这会影响效率。
五,应用--使用synchronized避免 因数据不一致性而导致读脏数据的情况
如下示例:
1 public class MyObject {
private String userName = "b";
private String passWord = "bb";
synchronized public void methodA(String userName, String passWord) {
this.userName = userN
Thread.sleep(5000);
}catch(InterruptedException e){
this.passWord = passW
synchronized public void methodB() {
System.out.println("userName" + userName + ": " + "passWord" + passWord);
methodA()负责更改用户名和密码。在现实中,一个用户名对应着一个密码。。。
methodB()负责读取用户名和密码。
如果methodB()没有用synchronized 修饰,线程A在调用methodA()执行到第7行,更改了用户名,因某种原因(比如在第9行睡眠了)放弃了CPU。
此时,如果线程B去执行methodB(),那么读取到的用户名是线程A更改了的用户名("a"),但是密码却是原来的密码("bb")。因为,线程A睡眠了,还没有来得及更改密码。&
但是,如果methodB()用synchronized修饰,那么线程B只能等待线程A执行完毕之后(即改了用户名,也改了密码),才能执行methodB读取用户名和密码。因此,就避免了数据的不一致性而导致的脏读问题。
本文永久更新链接地址:
相关资讯 & & &
& (09月01日)
& (08月31日)
& (09月01日)
& (08月31日)
& (08月31日)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款Java的synchronized加在方法上或者对象上有什么区别?
Java的synchronized可以加在方法上,也可以直接加在对象上,从而保证一段代码只能有一个线程在运行,保证线程的同步。
那么这两者究竟有啥区别呢?我们可以看下面的示例代码。
public class SyncTest {
public static synchronized void testSyncOnStaticMethod() {
System.out.println(“testSyncOnStaticMethod”);
Thread.sleep(10000);
} catch (InterruptedException e) {
public static void testSyncOnClass() {
synchronized (SyncTest.class) {
System.out.println(“testSyncOnClass”);
Thread.sleep(10000);
} catch (InterruptedException e) {
public synchronized void testSyncOnMethod() {
System.out.println(“testSyncOnMethod”);
Thread.sleep(10000);
} catch (InterruptedException e) {
public void testSyncOnThis() {
synchronized (this) {
System.out.println(“testSyncOnThis”);
Thread.sleep(10000);
} catch (InterruptedException e) {
public static void case1() {
// 先输出testSyncOnThis或者testSyncOnMethod
// 然后停顿10秒,再输出另一个
// 这个现象表明了
// public synchronized void func() {
// public void func() {
// synchronized (this) {
final SyncTest t1 = new SyncTest();
new Thread(new Runnable() {
public void run() {
t1.testSyncOnThis();
}).start();
new Thread(new Runnable() {
public void run() {
t1.testSyncOnMethod();
}).start();
public static void case2() {
// 先输出testSyncOnClass或者testSyncOnStaticMethod
// 然后停顿10秒,再输出另一个
// 这个现象表明了
// public synchronized static void staticFunc() {
// public static void staticFunc() {
// synchronized (SyncTest.class) {
new Thread(new Runnable() {
public void run() {
SyncTest.testSyncOnClass();
}).start();
new Thread(new Runnable() {
public void run() {
SyncTest.testSyncOnStaticMethod();
}).start();
public static void main(String[] args) {
从上面的代码我们可以看出synchronized加在方法上本质上还是等价于加在对象上的。
如果synchronized加在一个类的普通方法上,那么相当于synchronized(this)。
如果synchronized加载一个类的静态方法上,那么相当于synchronized(Class对象)。
在使用多线程的时候,知道这个是很关键的,因为synchronized的两种不用用法可能导致两段不相干的代码是互斥的,增加了同步的开销(例如这里的函数testSyncOnThis和testSyncOnMethod,他们在同一个对象this上加了锁),更严重的是可能导致死锁。
注:如果要试验,上面的case1和case2请分开运行(可以跑两次,每次注释掉其中一个语句),这样子可以看得比较清楚。
参考来源 .
是本站开发的一款收藏记录创意分享 ,开启高效之门的在线应用。点击: 收藏此文
你可能对这些文章感兴趣.
Copyright & 2014 java面试题Java&synchronized&关于锁的对象顺序问题
关于synchronized
&这东西就是看对象 目前也是很木乱 &还是要多敲 自己REBUG
坑总是会填满的
-----------------我是分割的小尾巴
下列是方法
public synchronized void methodA(int a, int b);
public synchronized void methodB(int a){
methodA(a, 0);
那么对于顺序问题怎么看呢
要明白两个问题,1.锁的对象是谁,2.谁持有了锁。
假设方法A和B是在同一个类Test中的两个方法。
Test t=new Test();&
t.methodB();
这个时候,methodB方法被调用时,因为加了synchronized
,需要先获得一个锁,这个锁的对象应该是t,也就是当前的这个Test类的实例,而获得锁的东西是线程,也就是说当前线程拿到了t的锁(而不是你说的B方法获得锁),这个时候B方法内调用methodA,因为A也加了synchronized,也需要获得一个锁,因为A和B都是Test类中的方法,所以当前线程要获得的锁的对象也是t。由于当前线程在执行B方法时已经持有了t对象的锁,因此这时候调用methodA是没有任何影响的,相当于方法A上没有加synchronized。
另一种情况:假设现在有两个Test类
Test t1=new Test();&
Test t2=new Test();&
t1.methodB();//此时当前线程持有了t1对象的锁
t2.methodB();//此时当前线程也持有了t2对象的锁
当前线程持有了两把锁,锁的对象分别是两个不同的Test类的实例t1和t2,互相没有影响。
再一种情况:假设在多线程环境下,两个线程都可以访问Test t=new Test();&
此时假设thread1里调用t.methodB();同时thread2里调用t.methodB()
这时假设thread1先抢到t对象的锁,那么thread2需要等待thread1释放t对象的锁才可以执行B方法。
结果像这样:
thread1获得t的锁--thread1执行methodB--thread1执行methodA--释放t的锁---thread2获得t的锁--thread2执行methodB--thread2执行methodA--释放t的锁。
如果是下面这个样子
public synchronized void methodA(int a, int b);
public synchronized void methodB(int a){
public static void
main(String [ ] args){
TT tt =new TT ();
tt.start();
tt.method B(int a);
}// 因为方法A和方法B锁定的是同一对象中的方法 为synchronized
锁定的是对象而不是方法 &那么当方法b先获得锁之后
&那么a就发生阻塞 必须等到方法b执行完毕之后在去执行方法a 因为方法b为主线程的调用
&会比开启新线程得到锁的速度要快
&所以要根据情况设定SLEEP的时候来确定需要的线程先得到锁
附一下代码
public class
test11 implements Runnable{
synchronized void A() throws InterruptedException{
System.out.println(Thread.currentThread().getName()+":"+"B值修改为1000");
System.out.println(Thread.currentThread().getName()+":"+"运行方法A");
Thread.sleep(5000);
System.out.println(Thread.currentThread().getName()+":"+"A"
synchronized void B() throws InterruptedException
System.out.println(Thread.currentThread().getName()+":"+"运行方法b");
Thread.sleep(2500);
System.out.println(Thread.currentThread().getName()+":"+"B"
public void
(InterruptedException e) {
Auto-generated catch block
e.printStackTrace();
static void main(String[] args) throws InterruptedException
=new test11();
Thread i =
new Thread(t);
& & i.start(); &
System.out.println(Thread.currentThread().getName()+":"+"运行方法main"+t.b);
main:运行方法b
main:B2000
Thread-0:B值修改为1000
Thread-0:运行方法A
main:运行方法main1000
已投稿到:
以上网友发言只代表其个人观点,不代表新浪网的观点或立场。Java线程同步:synchronized锁住的是代码还是对象
Java线程同步:synchronized锁住的是代码还是对象
在Java中,synchronized关键字是用来控制线程同步的,就是在多线程的环境下,控制synchronized代码段不被多个线程同时执行。synchronized既可以加在一段代码上,也可以加在方法上。
关键是,不要认为给方法或者代码段加上synchronized就万事大吉,看下面一段代码:
class&Sync&{&&&&&&&&public&synchronized&void&test()&{&&&&&&&&&&System.out.println("test开始..");&&&&&&&&&&try&{&&&&&&&&&&&&&&Thread.sleep(1000);&&&&&&&&&&}&catch&(InterruptedException&e)&{&&&&&&&&&&&&&&e.printStackTrace();&&&&&&&&&&}&&&&&&&&&&System.out.println("test结束..");&&&&&&}&&}&&&&class&MyThread&extends&Thread&{&&&&&&&&public&void&run()&{&&&&&&&&&&Sync&sync&=&new&Sync();&&&&&&&&&&sync.test();&&&&&&}&&}&&&&public&class&Main&{&&&&&&&&public&static&void&main(String[]&args)&{&&&&&&&&&&for&(int&i&=&0;&i&&&3;&i++)&{&&&&&&&&&&&&&&Thread&thread&=&new&MyThread();&&&&&&&&&&&&&&thread.start();&&&&&&&&&&}&&&&&&}&&}&&
运行结果:
test开始..
test开始..
test开始..
test结束..
test结束..
test结束..
可以看出来,上面的程序起了三个线程,同时运行Sync类中的test()方法,虽然test()方法加上了synchronized,但是还是同时运行起来,貌似synchronized没起作用。&
将test()方法上的synchronized去掉,在方法内部加上synchronized(this):
public&void&test()&{&&&&&&synchronized(this){&&&&&&&&&&System.out.println("test开始..");&&&&&&&&&&try&{&&&&&&&&&&&&&&Thread.sleep(1000);&&&&&&&&&&}&catch&(InterruptedException&e)&{&&&&&&&&&&&&&&e.printStackTrace();&&&&&&&&&&}&&&&&&&&&&System.out.println("test结束..");&&&&&&}&&}&&
运行结果:
test开始..
test开始..
test开始..
test结束..
test结束..
test结束..
一切还是这么平静,没有看到synchronized起到作用。&
实际上,synchronized(this)以及非static的synchronized方法(至于static synchronized方法请往下看),只能防止多个线程同时执行同一个对象的同步代码段。
回到本文的题目上:synchronized锁住的是代码还是对象。答案是:synchronized锁住的是括号里的对象,而不是代码。对于非static的synchronized方法,锁的就是对象本身也就是this。
当synchronized锁住一个对象后,别的线程如果也想拿到这个对象的锁,就必须等待这个线程执行完成释放锁,才能再次给对象加锁,这样才达到线程同步的目的。即使两个不同的代码段,都要锁同一个对象,那么这两个代码段也不能在多线程环境下同时运行。
所以我们在用synchronized关键字的时候,能缩小代码段的范围就尽量缩小,能在代码段上加同步就不要再整个方法上加同步。这叫减小锁的粒度,使代码更大程度的并发。原因是基于以上的思想,锁的代码段太长了,别的线程是不是要等很久,等的花儿都谢了。当然这段是题外话,与本文核心思想并无太大关联。
再看上面的代码,每个线程中都new了一个Sync类的对象,也就是产生了三个Sync对象,由于不是同一个对象,所以可以多线程同时运行synchronized方法或代码段。
为了验证上述的观点,修改一下代码,让三个线程使用同一个Sync的对象。
class&MyThread&extends&Thread&{&&&&&&&&private&Sync&&&&&&&&&public&MyThread(Sync&sync)&{&&&&&&&&&&this.sync&=&&&&&&&}&&&&&&&&public&void&run()&{&&&&&&&&&&sync.test();&&&&&&}&&}&&&&public&class&Main&{&&&&&&&&public&static&void&main(String[]&args)&{&&&&&&&&&&Sync&sync&=&new&Sync();&&&&&&&&&&for&(int&i&=&0;&i&&&3;&i++)&{&&&&&&&&&&&&&&Thread&thread&=&new&MyThread(sync);&&&&&&&&&&&&&&thread.start();&&&&&&&&&&}&&&&&&}&&}&&
运行结果:
test开始..
test结束..
test开始..
test结束..
test开始..
test结束..
可以看到,此时的synchronized就起了作用。&
那么,如果真的想锁住这段代码,要怎么做?也就是,如果还是最开始的那段代码,每个线程new一个Sync对象,怎么才能让test方法不会被多线程执行。&
解决也很简单,只要锁住同一个对象不就行了。例如,synchronized后的括号中锁同一个固定对象,这样就行了。这样是没问题,但是,比较多的做法是让synchronized锁这个类对应的Class对象。
class&Sync&{&&&&&&&&public&void&test()&{&&&&&&&&&&synchronized&(Sync.class)&{&&&&&&&&&&&&&&System.out.println("test开始..");&&&&&&&&&&&&&&try&{&&&&&&&&&&&&&&&&&&Thread.sleep(1000);&&&&&&&&&&&&&&}&catch&(InterruptedException&e)&{&&&&&&&&&&&&&&&&&&e.printStackTrace();&&&&&&&&&&&&&&}&&&&&&&&&&&&&&System.out.println("test结束..");&&&&&&&&&&}&&&&&&}&&}&&&&class&MyThread&extends&Thread&{&&&&&&&&public&void&run()&{&&&&&&&&&&Sync&sync&=&new&Sync();&&&&&&&&&&sync.test();&&&&&&}&&}&&&&public&class&Main&{&&&&&&&&public&static&void&main(String[]&args)&{&&&&&&&&&&for&(int&i&=&0;&i&&&3;&i++)&{&&&&&&&&&&&&&&Thread&thread&=&new&MyThread();&&&&&&&&&&&&&&thread.start();&&&&&&&&&&}&&&&&&}&&}&&
运行结果:
test开始..
test结束..
test开始..
test结束..
test开始..
test结束..
上面代码用synchronized(Sync.class)实现了全局锁的效果。
最后说说static synchronized方法,static方法可以直接类名加方法名调用,方法中无法使用this,所以它锁的不是this,而是类的Class对象,所以,static synchronized方法也相当于全局锁,相当于锁住了代码段。
作者:叉叉哥&& 转载请注明出处:&
发表评论:
TA的推荐TA的最新馆藏[转]&

我要回帖

更多关于 jquery对象转html代码 的文章

 

随机推荐