请教高手们一个问题
在Java中 用 synchronized 锁住同一个类中的两个方法A,B;
他的意思是 我用A时B也不能被用还是我用A时A不能用,用B时B不能用?
在Java中 用 synchronized 锁住同一个类中的两个方法A,B;
他的意思是 我用A时B也不能被用还是我用A时A不能用,用B时B不能用?
解决方案 »
- JAVA io 读写速度方面的问题 为啥笔记本比服务器快一倍
- JAVA中只有按值传递,这句话对么?
- JAXBContext生成XML,value如何显示在括号内
- java编绎时出现如下错误:需要为 class、interface 或 enum怎么办啊?
- 想写一个java对象池,有无代码可参考
- JTextField的问题,谢谢大家
- 我想问问关于抽象类的构造方法的问题
- jpopup menu 能够横过来吗?
- 谁有javaMUD游戏的源代码啊,输入文字,游戏就会出来一些选项。
- 图片路径的问题,很简单的
- 急~~~~FOP转PDF中文乱码,提示如下!
- 谁能做对这道题,我就拜他为师...大神请进(跑代码作弊无视之)
因为每个对象有一个对象锁,使用A方法的时候,拿了这个锁,所以可以执行,但是尝试再次调用A方法的时候,对象锁已经被拿走了,所以要等待A方法释放锁才能执行,同理,尝试调用B方法也不行,因为对象锁已经被拿走了,也要等A方法释放锁之后才能执行
(1)锁的对象是什么?按照你的意思,那么就是这个类的实例了,即非静态同步方法;那么方法A访问时,这个实例就加锁了,这个时候B不能访问了,因为如果可以访问,既不是意味着这个对象加料2次锁,方法B只能等A结束访问,对象锁释放了才能访问;
(2)要注意你锁的对象是这个实例,如果在NEW一个实例,是可以访问A或者B的,因为你加锁的不是这个新实例。
不知道你有没有明白我的意思,这个是就学习同步方法最重要的注意事项了。然后最后一点是你尽量用同步代码块替代同步方法,这样节省锁的范围,提高性能。
package edu.cuit.wlgcx;class Demo {
private int i = 100; synchronized int setI(int y) {
return i = i - y;
} synchronized int getI() {
return i;
}}public class SynchronrizedTest implements Runnable { private Demo demo = new Demo(); public static void main(String[] args) { SynchronrizedTest test1 = new SynchronrizedTest(); Thread thread1 = new Thread(test1, "线程1");
Thread thread2 = new Thread(test1, "线程2");
thread1.start();
thread2.start(); } @Override
public void run() {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} this.setI(10);
System.out.println(demo.getI() + Thread.currentThread().getName()); }
} int setI(int y) {
return demo.setI(y);
}} 如果多次执行就会发现输出结果会不一样
有木有这种情况,a执行完A后,已经释放了A的锁,还未获得B的锁,但是b线程获得了A的锁,当b释放A的锁时,a获得了B的锁,此时数据依然被a修改过了,这种问题怎么解决呢?
import java.util.concurrent.locks.ReentrantLock;class Demo {
private int i = 100; int setI(int y) {
System.out.println("减去" + y);
return i = i - y;
} int getI() {
return i;
}}public class SynchronrizedTest implements Runnable {
Lock lock = new ReentrantLock();
private Demo demo = new Demo(); public static void main(String[] args) { SynchronrizedTest test1 = new SynchronrizedTest(); Thread thread1 = new Thread(test1, "线程1");
Thread thread2 = new Thread(test1, "线程2");
thread1.start();
thread2.start(); } public void run() {
for (int i = 0; i < 5; i++) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
lock.lock();
System.out.println(Thread.currentThread().getName() + "操作之前: " + demo.getI());
this.setI(10);
System.out.println(Thread.currentThread().getName() + "操作之后: " + demo.getI());
System.out.println();
lock.unlock();
}
} int setI(int y) {
return demo.setI(y);
}}
LZ,那是因为你的setI和getI是独立的两个方法,不在同一个synchronized块里,所以他们之间的调用有时间上的间隙,这样,在这个间隙中其他线程先执行的话,就会导致setI和getI的结果不同步this.setI(10);
//这里就是时间间隙
System.out.println(demo.getI() + Thread.currentThread().getName());
把这两句代码写到同一个synchronized块才能保证setI和getI之间的一致
即
syncronized(this) { //其他线程会在这里等待
//(当然,这样的前提是你的线程都是执行相同的这段代码,
//否则,因为这里的this和demo的synchronized不是同一个对象,也不能保证setI和getI同步)
this.setI(10);
System.out.println(demo.getI() + Thread.currentThread().getName());
}