java之学习多线程(四)

本文探讨了多线程环境下票务系统中出现的票数负数问题,并通过同步代码块与同步方法解决了该问题。文章还讨论了同步机制如何确保数据安全性和可能引发的性能降低及死锁风险。

线程的同步与死锁

public class lock_line {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread3 Me = new MyThread3();
		new Thread(Me ,"one").start();
	    new Thread(Me ,"three").start();
	    new Thread(Me,"two").start();
	}

}

class MyThread3 implements Runnable{
	int ticket1 = 6;
	@Override
	public void run(){
		
		for(int x = 0;x < 10;x++){
			if(this.ticket1 > 0){
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"卖票,ticket="+ this.ticket1--);
			}
		}
	}
}
结果

one卖票,ticket=6
three卖票,ticket=5
two卖票,ticket=4
one卖票,ticket=3
three卖票,ticket=2
two卖票,ticket=1
one卖票,ticket=0
three卖票,ticket=-1
出现负数,说明在同一个时间段内有多个线程在运作,修改了ticket,使票数不为零的判断之后的ticket变为负数。

解决的方法就是:同步,是多个操作在同一个时间里只能有一个线程进行,其他线程要等待此线程完成后才可以继续执行。

方法一:同步代码块( synchronized(同步对象){同步代码})

public class lock_line {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread3 Me = new MyThread3();
		
		new Thread(Me ,"one").start();
	    new Thread(Me ,"three").start();
	    new Thread(Me,"two").start();
	}

}

class MyThread3 implements Runnable{
	int ticket1 = 6;
	@Override
	public void run(){
		
		for(int x = 0;x < 10;x++){
			synchronized(this){
			if(this.ticket1 > 0){
				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+"卖票,ticket="+ this.ticket1--);
			}
		}
		}
	}
}

方法二:同步方法

public class lock_line {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		MyThread3 Me = new MyThread3();
		
		new Thread(Me ,"one").start();
	    new Thread(Me ,"three").start();
	    new Thread(Me,"two").start();
	}

}

class MyThread3 implements Runnable{
	int ticket1 = 6;
	@Override
	public void run(){
		
		for(int x = 0;x < 10;x++){
			this.test();
		}
	}
	public synchronized void test(){
		if(this.ticket1 > 0){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"卖票,ticket="+ this.ticket1--);
		}
	}
}

在此处说明一个问题,加入同步后程序会变慢许多,所以代码性能会减低,但数据安全性会很高。

多线程访问同一资源时一定要考虑到同步的问题,过多的同步会带来死锁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值