java-synchronized方法

  在java中,为了避免多个线程对同一资源访问操作时候的干扰脏读,可以用synchronized来同步方法

class MyObject{
	public synchronized void methodA(){
		try{
			System.out.println("begin methodA threadName="
				+ Thread.currentThread().getName());
			Thread.sleep(5000);
			System.out.println("end");
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}

class ThreadA extends Thread{
	private MyObject object;
	public ThreadA(MyObject object){
		this.object = object;
	}

	public void run(){
		object.methodA();
	}
}

public class test{
	public static void main(String[] args){
		MyObject object = new MyObject();
		ThreadA a = new ThreadA(object);
		a.setName("A");
		ThreadA b = new ThreadA(object);
		b.setName("B");
		a.start();
		b.start();
        }
}

运行结果:

线程B要等到线程A执行完同步方法才能去执行。

synsynchronized同步锁,锁的是它的一个对象,多个对象有多个同步锁

class HasSelfPrivateNum{
	private int num = 0;
	synchronized public void  addI(String username){
		try{
			if(username.equals("a")){
				num = 100;
				System.out.println("a set over!");
				Thread.sleep(2000);
			}else{
				num = 200;
				System.out.println("b set over");
			}
                        System.out.println(username + " num=" + num);
                     }catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
}

class ThreadA extends Thread{
	private HasSelfPrivateNum numRef;

	public ThreadA(HasSelfPrivateNum numRef){
		this.numRef = numRef;
	}

	public void run(){
		numRef.addI("a");
	}

}

class ThreadB extends Thread{
	private HasSelfPrivateNum numRef;

	public ThreadB(HasSelfPrivateNum numRef){
		this.numRef = numRef;
	}

	public void run(){
		numRef.addI("b");
	}
}

public class test2{
	public static void main(String[] args){
		HasSelfPrivateNum numRef1 = new HasSelfPrivateNum();
		HasSelfPrivateNum numRef2 = new HasSelfPrivateNum();
		ThreadA athread = new ThreadA(numRef1);
		athread.start();
		ThreadB bthread = new ThreadB(numRef2);
		bthread.start();
	}	
}

执行结果:

     虽然线程在HasSelfPrivateNum中使用了关键字synchronized,但打印却不是同步的,是交叉的。关键字synchronized取得的锁都是对象锁,而不是把一段代码或方法(函数)当作锁。所以在第一个例子中,哪个线程先执行带synchronized的方法,哪个线程就持有该方法所属对象的锁,其他线程想要执行此对象synchronized的其他方法,或者synchronized块,都会被阻塞等待。如果多个线程访问的是多个对象,如此例,每个对象有自己的synchronized锁,相互独立。

     synchronized方法被调用了,但非synchronized方法同时可以被调用

class MyObject{
	public synchronized void methodA(){
		try{
			System.out.println("begin methodA threadName="
				+ Thread.currentThread().getName());
			Thread.sleep(5000);
			System.out.println("end endTime=" + System.currentTimeMillis());
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}

	public  void methodB(){
		try{
			System.out.println("begin methodB threadName="
				+ Thread.currentThread().getName() 
				+ " beginTime=" + System.currentTimeMillis());
			Thread.sleep(5000);
			System.out.println("end endTime=" + System.currentTimeMillis());
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}

class ThreadA extends Thread{
	private MyObject object;
	public ThreadA(MyObject object){
		this.object = object;
	}

	public void run(){
		object.methodA();
	}
}

class ThreadB extends Thread{
	private MyObject object;
	public ThreadB(MyObject object){
		this.object = object;
	}

	public void run(){
		object.methodB();
	}
}

public class test{
	public static void main(String[] args){
		MyObject object = new MyObject();
		ThreadA a = new ThreadA(object);
		a.setName("A");
		ThreadB b = new ThreadB(object);
		b.setName("B");
		a.start();
		b.start();

	}
}

运行结果:

 当持有一个synchronized锁后,可以重入其他synchronized方法,避免了死锁

class  Service{
	synchronized public void Service1(){
		System.out.println("service1");
		Service2();
	}

	synchronized public void Service2(){
		System.out.println("service2");
		Service3();
	}

	synchronized public void Service3(){
		System.out.println("service3");	
	}
}

class MyThread extends Thread{
	public void run(){
		Service service = new Service();
		service.Service1();
	}
}

public class test3{
	public static void main(String[] args){
		MyThread t = new MyThread();
		t.start();
	}	
}

运行结果:

结论:

1)A线程先持有object对象的锁,B线程可以以异步的方式调用object对象中的非synchronized类型的方法。

2)A线程先持有object对象的锁,B线程如果在这时调用了object对象中的synchronized类型的方法则需要等待。

  最后要说明,如果在执行synchronized方法出现异常,其所持有的锁会自动释放。


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值