javaSE-线程安全

线程安全问题

导致安全问题的出现的原因:
多个线程访问出现延迟。
线程随机性 。
注:线程安全问题在理想状态下,不容易出现,但一旦出现对软件的影响是非常大的。
/*
线程安全问题。
原因:

1,多个线程在同时处理共享数据。
2,线程任务中的有多条代码在操作共享数据。

安全问题成因就是:一个线程在通过多条操作共享数据的过程中,其他线程参与了共享数据的操作。
				导致到了数据的错误。


想要知道你的多线程程序有没有安全问题:
只要看线程任务中是否有多条代码在处理共享数据。


解决:
一个线程在通过多条语句操作共享数据的过程中,不允许其他线程参与运算。就哦了。

如何代码体现呢?
Java中提供了同步代码块进行引起安全问题的代码封装。

格式:
synchronized(对象)
{
	//需要被同步的代码;
}


同步:
	好处:解决了多线程的安全问题。
	弊端:降低了效率。

同步的前提:
	1,至少有两个线程在同步中。
	2,必须保证同步使用的是同一个锁。


*/
class Ticket implements Runnable
{
	private int num = 100;
	Object obj = new Object();
	public void run()
	{
		while(true)
		{
			synchronized(obj)
			{
				if(num>0)
				{
					try{Thread.sleep(10);}catch(InterruptedException e){}//让线程在这里小睡,导致了 0 -1 等错误票的产生。
	//				出现了线程安全问题。
					System.out.println(Thread.currentThread().getName()+"..sale:"+num--);
				}
			}
		}
	}
}
public class ThreadSafe {

	public ThreadSafe() {
		// TODO Auto-generated constructor stub
	}
	public static void main(String[] args) 
	{
		Ticket t = new Ticket();

		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
		Thread t3 = new Thread(t);
		Thread t4 = new Thread(t);
		t1.start();
		t2.start();
		t3.start();
		t4.start();
	}

}


同步(synchronized)

格式:
synchronized(对象)
{
需要同步的代码;
}
同步可以解决安全问题的根本原因就在那个对象上。
该对象如同锁的功能。
同步的前提:
同步需要两个或者两个以上的线程。
多个线程使用的是同一个锁。
未满足这两个条件,不能称其为同步。
同步的弊端:
当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。

注意事项


synchronized(new Object()){
	
	
}
new 出来的对象没有引用指向它  
其实就是没个线程都加了一把锁 以上的两条要求都没有满足  

同步函数

格式:
在函数上加上synchronized修饰符即可。
思考:同步函数用的是哪个锁呢?

/*
同步的第二种表现形式。

同步函数。


问题:同步函数使用的锁是什么呢?
同步函数使用的锁,应该是this。


同步函数和同步代码块的区别?
同步函数使用的固定锁this。
同步代码块使用的锁是可以指定的。

*/
public synchronized/**/ void sale()//同步函数。
	{
		if(num>0)
		{
			try{Thread.sleep(10);}catch(InterruptedException e){}
			System.out.println(Thread.currentThread().getName()+"..func:"+num--);
		}
	}
若同步函数和同步代码块一起使用 还是不安全 相当于又使用了多把锁

在开发中如果之使用一个锁就够了的话 使用同步函数  
其他程序尽量使用同步代码块   锁是可以指定了  有灵活性


静态同步函数

/*
静态同步函数使用的锁是什么?
就是所在类的 类名.class 字节码文件对象。


*/
class Ticket implements Runnable
{
	private static  int num = 100;
	boolean flag = true;
	Object obj = new Object();
	public void run()
	{
		if(flag)
		{
			while(true)
			{
				synchronized(Ticket.class)//super.getClass()
				{
					if(num>0)
					{
						try{Thread.sleep(10);}catch(InterruptedException e){}
						System.out.println(Thread.currentThread().getName()+"..obj:"+num--);
					}
				}
			}
		}
		else
			while(true)
			{			
				this.sale();
			}
	}

	public static synchronized/**/ void sale()//static同步函数。
	{
		if(num>0)
		{
			try{Thread.sleep(10);}catch(InterruptedException e){}
			System.out.println(Thread.currentThread().getName()+"..func:"+num--);
		}
	}
}

class ThreadDemo5_Ticket_StaticLock
{
	public static void main(String[] args) 
	{
		Ticket t = new Ticket();
		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
//		Thread t3 = new Thread(t);
//		Thread t4 = new Thread(t);
		t1.start();
		try{Thread.sleep(10);}catch(InterruptedException e){}
		t.flag = false;
		t2.start();
//		t3.start();
//		t4.start();
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值