Java多线程编程之对象及变量的并发访问(synchronized和volatile关键字)

1、synchronized

(1)关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法当作锁。

对象方法内的临时变量为线程安全的,对象的成员变量(实例变量)为非线程安全的。

public class MyObject {
	synchronized public void methodA() {
		try {
			System.out.println("begin methodA threadName="+Thread.currentThread().getName());
			Thread.sleep(5000);
			System.out.println("end methodA endTime="+System.currentTimeMillis());
		}catch( InterruptedException e) {
			e.printStackTrace();
		}
	}
	synchronized public void methodB() {
		try {
			System.out.println("begin methodB thread-"+Thread.currentThread().getName()+" beginTime="+System.currentTimeMillis());
			Thread.sleep(5000);
			System.out.println("end methodB endTime="+System.currentTimeMillis());
		}catch( InterruptedException e) {
			e.printStackTrace();
		}
	}
}
public class ThreadA extends Thread {
	private MyObject object;
	public ThreadA(MyObject object) {
		this.object=object;
	}
	@Override
	public void run() {
		super.run();
		this.object.methodA();
	}
}

public class ThreadB extends Thread {
	private MyObject object;
	public ThreadB(MyObject object) {
		this.object=object;
	}
	@Override
	public void run() {
		super.run();
		this.object.methodB();
	}
}
public class Run {
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyObject object=new MyObject();
		ThreadA a=new ThreadA(object);
		a.setName("A");
		ThreadB b=new ThreadB(object);
		b.setName("B");
		a.start();
		b.start();
	}

}

 当A线程调用object对象加入synchronized关键字的X方法时,A线程就获得了X方法所在对象的锁,其他线程必须等A线程执行完毕后才可以调用X方法其他具有synchronized关键字的非X方法

 (2)synchronized具有锁重入功能

即在一个synchronized方法/块的内部调用本类的其他synchronized方法/块时,是永远可以得到锁的。

public class Service {
	synchronized public void service1() {
		System.out.println("service1");
		this.service2();
	}
	synchronized public void service2() {
		System.out.println("service2");
		this.service3();
	}
	synchronized public void service3() {
		System.out.println("service3");
	}
}

可重入锁也支持再父子继承的环境中。即在子类的synchronized方法中调用父类的synchronized方法。

(3)synchronized不具有继承性。

在子类方法重写父类synchronized方法时,必须显示的写出synchronized关键字,否则子类的该方法不具有同步性。

(4)synchronized代码块/方法中出现异常时,锁会自动释放。

(5)synchronized(非this 对象x)代码块中的程序与synchronized(this)中的程序是异步的,不与其他同步方法争抢this锁。

             1、当多个线程同时执行synchronized(x){}同步代码块时呈现同步效果

              2、当其它线程执行x对象中synchronized同步方法是呈现同步效果

              3、当其它线程执行x对象中synchronized同步方法块时也呈现同步效果。

(6)synchronized加到static静态方法上是给Class类上锁,同一个类的不同对象只能同步访问该方法;

而加到非static方法上,则是同一个对象在不同线程间只能同步访问该方法。

(7)一般同步synchronized代码块不使用String作为锁对象,而用一个实例化对象比如new Object(),这是因为JVM中具有String常量池缓存功能。

2、volatile关键字

强制从公共堆栈中取得变量的值,而不是从线程私有数据栈中取得变量的值。

不具有将线程工作内存的变量与公共内存中的变量同步的功能。因为变量在内存中的load、use、assign操作具有非原子性。

除了使用synchronized外,可以采用将变量声明为原子类的方法实现同步,如:AtomicInteger count(声明一个整型变量count)。

同步synchronized不仅可以解决一个线程看到对象处于不一致的状态,还可以保证进入同步方法/代码块的每个线程,都看到由同一个锁保护之前所有的修改效果

public class Service {
	private boolean isContinue=true;
	public void runMethod() {
		String any=new String();
		while(isContinue==true) {
			synchronized(any) {
				/*一旦isContinue的值在其他线程被修改,会立刻反映到当前线程中*/
			}
		}
	}
	public void stopMethod() {
		this.isContinue=false;
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值