多线程(二)

5、线程同步(保证资源合理共享)

线程安全问题:多线程环境中操作共享资源,由于多个线程争抢CPU执行权具有随机性,所以会出现资源调度混乱的情况 。

线程同步:可以形象的理解为给共享资源配一把“锁”,每次只有一个线程可以访问 ,从而防止资源访问的冲突 。


Java提供同步块来实现线程同步:

public class ThreadTwo implements Runnable{

	private int num=10;
	
	//创建“锁”对象
	private Object mutex=new Object();
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			//进入同步代码块之前,三个线程都在争抢
			/**
			 * 同步块
			 */
			synchronized (mutex) {
				//进来之后只要一个线程行代码块
				if(num>0){
					try {
						Thread.sleep(1000);//当前线程睡眠1秒
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					System.out.println(Thread.currentThread().getName()+":"+num--);
				}
			}
		}
	}
}

也可以用同步方法来实现线程同步:

public class ThreadTwo implements Runnable{

	private int num=10;
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(true){
			//进同步代码块之前,三者都在抢
			sale();
		}
	}
	
	/**
	 * 同步方法
	 */
	public synchronized void sale(){
		if(num>0){
			try {
				Thread.sleep(1000);//当前线程睡眠1秒
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+":"+num--);
		}
	}
}

创建线程并启动:

public class ThreadTwoMain {
	
	public static void main(String[] args) {
		//创建接口对象
		Runnable r=new ThreadTwo();
		//根据接口对象创建线程对象
		Thread t1=new Thread(r, "林志玲");
		Thread t2=new Thread(r, "林心如");
		Thread t3=new Thread(r, "蔡依林");
		
		t1.start();
		t2.start();
		t3.start();
	}
}

线程同步之前,输出:

林志玲:10
林志玲:9
林志玲:8
林志玲:7
林志玲:6
林心如:5
林心如:4
蔡依林:3
林心如:2
林心如:1
林心如:0
林心如:-1

线程同步之后:

林志玲:10
林志玲:9
林志玲:8
林志玲:7
林志玲:6
林心如:5
林心如:4
蔡依林:3
林心如:2
林心如:1

线程同步之前,当num=1时,三个线程先后获取到了CPU的执行权,

线程1执行num--,输出1,num再减1;

线程2执行num--,输出0,num再减1;

线程3执行num--,输出-1,num再减1;

所以会出现0,-1 。

线程同步之后,只有一个线程能够执行共享代码,所以输出正常 。


6、死锁

当两个或多个线程之间同时等待对方释放资源,就会形成线程之间的死锁。


同步嵌套会导致死锁,可以形象地理解为,线程A需要线程B的“锁”才能继续执行,同样,线程B也需要线程A的“锁”才能继续执行,二者“僵持”,形成死锁 。

代码示例:

//定义两把锁
public class MyLock {
	public static Object objA=new Object();
	public static Object objB=new Object();
}

//死锁代码
public class DieLock implements Runnable{

	private boolean flag;
	
	public DieLock(boolean flag){
		this.flag=flag;
	}
	
       @Override
    public void run() {
        if(flag){
            //A获取自己的锁
            synchronized (MyLock.objA) {
                System.out.println("objA First!");
                //A要获取B的锁,但是B在用
                synchronized (MyLock.objB) {
                    System.out.println("objB Second!");
                }
            }
        }else{
            //B获取自己的锁
            synchronized (MyLock.objB) {
                System.out.println("objB First!");
                //B要获取A的锁,但是A在用
                synchronized (MyLock.objA) {
                    System.out.println("objA Second!");
                }
            }
        }
    }
}

//创建线程并启动
public class DieLockMain {
	
	public static void main(String[] args) {
		Thread A=new Thread(new DieLock(true));
		Thread B=new Thread(new DieLock(false));
		
		A.start();
		B.start();
	}
}

输出:

objA First!
objB First!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值