一、安全与同步
1、如果是多个线程,也许会发生重复的错误
2、安全问题是由 <全局变量> 和< 静态变量 >引起的
3、解决安全问题就需要 同步线程
二、三种同步方式
1、同步代码块:
关键字 synchronized,格式:
格式:
synchronized(锁对象){
可能存在线程安全问题的代码块
}
public class synchronized00 implements Runnable{
private int ticket =50;
//创建一个锁对象
String N = new String();
@Override
public void run() {
while(true) {
//使用synchronized同步代码块
synchronized (N) {
if (ticket > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":—>>" + "第" + ticket + "票");
ticket--;
}
}
}
}
2、同步方法:格式:
修饰符列表 synchronized 返回值类型 方法名(参数列表){
可能存在线程安全问题的代码块
}
public class synchronized02 implements Runnable{
private int ticket =50;
@Override
public void run() {
while(true) {
method();
}
}
//创建一个同步方法
public synchronized void method () {
if (ticket > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":—>>" + "第" + ticket + "票");
ticket--;
}
}
3、锁机制
关键字 lock
java.util.concurrent.locks.Lock;
java.util.concurrent.locks.ReentrantLock 实现 Lock接口
Lock接口中的两种方法:
void lock() 获取锁
void unlock() 释放锁
使用步骤:
1、使用多态方法创建一个ReentrantLock对象
2、可能存在线程安全问题的代码块 前面 使用 lock
3、可能存在线程安全问题的代码块 后面 使用 unlock
public class Lock00 implements Runnable{
private int ticket =50;
//创建一个Reentrantlock对象
Lock lock1 = new ReentrantLock();
@Override
public void run(){
while(true) {
//获取锁
lock1.lock();
if (ticket > 0) {
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + ":—>>" + "第" + ticket + "票");
ticket--;
}
lock1.unlock();//释放锁
}
}
//可以使用finally,将打印语句放在try中,不管程序是否异常,锁都会起作用
这是上面的主方法代码
public class synchronized01 {
public static void main(String[] args) {
Lock00 sy = new Lock00();
Thread t = new Thread(sy);
Thread t1 = new Thread(sy);
Thread t2 = new Thread(sy);
t.start();
t1.start();
t2.start();
}