多线程基础之同步代码块

           

    同步方法在同一时刻只能锁定一个对象(即同步方法所属的对象),在并发执行中有时需要锁定的对象不止一个。另外,同步方法会形象执行效率,因此,应该尽量减少同步范围,提高程序的并发性。而同步代码块可以解决上述问题。

synchronized (<资源对象引用>){
    //需要同步的代码
}
(1)资源对象引用指向的是要被锁定的资源对象,同步代码块中的代码是对资源进行的操作,这些代码在同一时刻不允许多个线程执行。

(2)线程必须先获得资源对象引用所指向的对象的锁(注意:所用的锁,因为可以存在有多个引用),才能执行同步代码块中的代码。

(3)同步代码块中的线程一样可以调用资源对象的wait方法,释放锁,进入等待池等待,一样可以使用notify()/notifyAll()去唤醒等待池中的等待线程。

(4)同步代码块执行结束,锁释放。

注意:java中资源对象的线程等待池不止一种,例如有调用wait方法后进入的wait资源等待池,也有等待获得锁的锁等待池,锁等待池中的线程在锁被释放后会自动尝试再次获取锁,而wait资源等待池中的 线程只有在wait时间到或收到notifyAll的通知才唤醒执行。当然有可能线程在wait资源等待池中被唤醒后由于没有获得锁,进入了锁等待池。

package test11;

public class MyThread extends Thread{
	//该引用为资源对象
	private Object resource;
	
	public MyThread(){}
	public MyThread(String name,Object resource){
		this.setName(name);
		this.resource = resource;
	}
	@Override
	public void run() {
		//同步语句块
		synchronized (resource) {
			System.out.println(this.getName()+"线程获得了锁,访问了资源!");
			System.out.println(this.getName()+"线程带着锁去休息了。。。");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(this.getName()+"线程醒了代码执行完,锁释放了!");
		}
	}
	

	
}

package test11;

public class Main {
	public static void main(String[] args) {
		
		//创建资源对象
		Object  resource = new Object();
		//创建线程,并将资源对象传给每一个线程
		Thread t1 = new MyThread("t1",resource);
		Thread t2 = new MyThread("t2",resource);
		t1.start();
		t2.start();

	}
}

运行结果:

t1线程获得了锁,访问了资源!
t1线程带着锁去休息了。。。
t1线程醒了代码执行完,锁释放了!
t2线程获得了锁,访问了资源!
t2线程带着锁去休息了。。。
t2线程醒了代码执行完,锁释放了!

注意:(1)sleep方法并不会释放锁
           (2)调用的wait(),notify(),notifyAll()方法都属于被锁定的资源对象 ,锁定的是谁,只能调用谁的这些方法

线程的死锁:java中死锁的含义是:线程之间互相等待对方释放资源对象的锁,而每个线程有持有其他线程需要的锁,造成几个线程出处在永久的相互等待之中。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值