线程安全问题
导致安全问题的出现的原因:
多个线程访问出现延迟。
线程随机性 。
注:线程安全问题在理想状态下,不容易出现,但一旦出现对软件的影响是非常大的。
多个线程访问出现延迟。
线程随机性 。
注:线程安全问题在理想状态下,不容易出现,但一旦出现对软件的影响是非常大的。
/*
线程安全问题。
原因:
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(对象)
{
需要同步的代码;
}
同步可以解决安全问题的根本原因就在那个对象上。
该对象如同锁的功能。
同步的前提:
同步需要两个或者两个以上的线程。
多个线程使用的是同一个锁。
未满足这两个条件,不能称其为同步。
同步的弊端:
当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。
注意事项
synchronized(new Object()){
}
new 出来的对象没有引用指向它 其实就是没个线程都加了一把锁 以上的两条要求都没有满足
同步函数
格式:
在函数上加上synchronized修饰符即可。
思考:同步函数用的是哪个锁呢?
在函数上加上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 字节码文件对象。
*/
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();
}
}