请问通过下面这种方法能起到防止haha()和run()中的synchronized中的内容同时执行的作用吗?
public class A{
public synchronized void haha(){
}
class B extends TimerTask{
@Override
public void run(){
synchronized(A.this){
}
}
}
}
public class A{
int value = 0;
final int NUMBER = 1000000;
public synchronized void haha(){
for (int i = 0; i < NUMBER; i++)
value ++;
}
class B extends TimerTask{
@Override
public void run(){
synchronized(A.this){
for (int i = 0; i < NUMBER; i++)
value ++;
}
}
}
public static void main(String args[]) throws InterruptedException {
A a = new A();
B b = a.new B();
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2);
executor.scheduleWithFixedDelay(b, 1, 1, TimeUnit.SECONDS);
executor.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
a.haha();
}
}, 1, 1, TimeUnit.SECONDS);
Thread.sleep(1000 * 9 + 500);
executor.shutdownNow();
System.out.printf("value: %d\n", a.value);
}
}
不能,你的代码只能保证两个haha或者两个run不能同时运行
你需要用lock来实现haha和run的同步
注意,要java8以上才支持lock
public class A{
private Lock lock = new ReentrantLock();
public synchronized void haha(){
lock.lock();
...
lock.unlock();
}
class B extends TimerTask{
@Override
public void run(){
lock.lock();
...
lock.unlock();
}
}
}
}
除了synchronized,可以锁lock实现同步
public class LockTest {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
final Business business = new Business();
ExecutorService service = Executors.newFixedThreadPool(3);
for(int i=0;i<3;i++){
service.execute(new Runnable(){
public void run(){
business.service();
}
});
}
service.shutdown();
}
}
class Business{
private int count = 0;
Lock lock = new ReentrantLock();
public void service(){
lock.lock();
count++;
try {
Thread.sleep(10);
System.out.println(count);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
lock.unlock();
}
}
}
这个是同步锁范围的问题
public class A{
public synchronized void haha(){ // 这样写时锁住同一对象的方法,new两个A在不同线程里运行haha是不同步的
}
class B extends TimerTask{
@Override
public void run(){
synchronized(A.this){ // 这样写是全局锁,锁住的是A这个类,但是这里写得又有点奇怪,为什么B类要用A类加锁
}
}
}
}
不能的,如果你需要两个方法不能同时执行,最好的方法是使用同一把锁。比如使用A.class作为锁,而不是A.this .A.this不能保证两个实例运行时同时进入两个方法。
不知道为什么我的回复被删除了。我的答案是可以的,还写了测试代码验证也是可以的。这不是很好的方式,但确实是可以。
@系统管理员,实在的回复也能被删!!!
截图为证,已经不止一次删了我的实在回复了。
不能。两个锁是在不同的对象上面。
你这个是锁的实例,两个方法不能同时运行要锁同一个对象
可以的,两个锁对象是同一个,这是非静态内部类对象的创建方式,A a = new A(); B b = a.new B();像这种问题自己实验一下就清楚了,
public static void main(String[] args){
g g0 = new g();
g0.haha();
g0.new B().run();
}
public synchronized void haha(){
System.out.println(this);
}
class B extends TimerTask{
@Override
public void run(){
synchronized(this){
System.out.println(this);
}
}
}
synchronized 方法锁是当前对象,下面的run也是当前对象。如果你的这两个方法执行都是同一个A对象那么可以达到你的预期,如果haha是一个对象,run是另一个对象的内部类对象,那么达不到同时锁的预期,望采纳