1. 同步代码块
synchronized(锁对向){
可能出现线程安全问题的代码块
}
注意:
1. 通过代码块中的锁对象,可以使用任意的对象
2. 必须保证多个线程使用的锁对象是同一个
3. 锁对象的作用:把同代码块锁住,只让一个线程在同步代码块中执行
private int n = 100;
Object obj = new Object();
@Override
public void run() {
while(true){
synchronized (obj){
if(n > 0){
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "-->" + n);
n--;
}
}
}
}
2.同步方法
修饰符 synchronized 返回值类型 方法名(参数列表){
可能会出现线程安全问题的代码
}
锁对象是this
修饰符 static synchronized 返回值类型 方法名(参数列表){
可能会出现线程安全问题的代码
}
锁对象是本类的class属性
private int n = 100;
@Override
public void run() {
while(true){
pay();
}
}
public synchronized void pay(){
if(n > 0){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "-->" + n);
n--;
}
}
3. Lock锁
Lock接口中的方法:
void lock() 获取锁
void unlock() 释放锁
使用步骤:
1. 在成员位置创建一个Reentrantlock对象
2. 在可能会出现安全问题代码前调用Lock接口中lock方法获取锁
3. 在可能会出现安全问题代码后调用Lock接口中unlock方法释放锁
private int n = 100;
Lock l = new ReentrantLock();
@Override
public void run() {
while(true){
l.lock();
if(n > 0){
try {
Thread.sleep(10);
System.out.println(Thread.currentThread().getName() + "-->" + n);
n--;
} catch (InterruptedException e) {
e.printStackTrace();
}
finally {
l.unlock();
}
}
}
}