多线程的锁
为什么需要锁?
产生安全问题的原因:
1.线程任务中有处理到共享的数据。
2.线程任务中有多条对共享数据的操作。
一个线程在操作共享数据的过程中,其他线程参与了运算,造成了数据的错误。
解决的思想:
只要保证多条操作共享数据的代码在某一时间段,被一条线程所执行,在执行期间不允许其他线程参与运算。
如何保证?
1.同步代码块:
synchronized(对象)//对象的左右就是锁
{
需要同步的代码
}
2.同步函数:
public synchronized void add(int n)//同步函数使用的是this
{
}
//函数需要被对象调用,同步函数使用的锁就是this。
好处:解决了多线程的安全问题。
弊端:减低效率(其他线程需要先进行判断等待)
前提:多个线程在同步中必须使用同一个锁,这才是同步。
使用的区别:
如果说,一个类中如果需要多个锁,这时可以考虑同步函数,使用this,写法简单。
但是,一个类中如果需要多个锁,还有多个类中需要使用同一个锁,这时只能使用同步代码块。
**建议主要使用同步代码块。
例 :1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23class SaleTicket implements Runnable
{
private int tickets = 100;
Object obj = new Object();
public void run()
{
while (true)
{
synchronized(obj)
{
if(ticket>0)
{
try{
Thread.sleep(10);//让线程在这里停一下
}
catch(InterruptedException e)
{
}
}
}
}
}
}
如果同步函数被static修饰
static方法随着类加载,这时不一定有该类的对象,但是一定有一个该类的字节码文件对象。
这个对象的简单表示方法就是 类名.class 描述类是用Class