1, 同步方法
2, 同步代码块
3, 使用Lock锁
4, 比较同步方法,同步代码块和Lock锁的区别
如何解决线程安全的问题
1,同步方法,具体实现如下:
public static void main(String[] args) {
//定义三个线程分别开始购物
Window window = new Window();
Thread t1 = new Thread(window);
Thread t2 = new Thread(window);
Thread t3 = new Thread(window);
t1.setName("拼夕夕");
t2.setName("京东");
t3.setName("淘宝");
t1.start();
t2.start();
t3.start();
}
}
class Window implements Runnable{
//一共有1w块钱,拼夕夕上每次购物50元,京东上每次购物300,淘宝每次购物150
private int money = 10000;
@Override
public void run() {
while (true){
if(money > 0) {
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (money>0){
pay();
}else {
break;
}
}else {
break;
}
}
}
public synchronized void pay(){
System.out.print(Thread.currentThread().getName()+":购了一次物");
if(Thread.currentThread().getName().equals("拼夕夕")){
money -= 50;
}
if(Thread.currentThread().getName().equals("京东")){
money -= 300;
}
if(Thread.currentThread().getName().equals("淘宝")){
money -= 150;
}
System.out.println("剩余的钱为"+money);
}
2,同步代码块,具体实现如下:
public static void main(String[] args) {
//定义三个线程分别开始卖票
Window window = new Window();
Thread t1 = new Thread(window);
Thread t2 = new Thread(window);
Thread t3 = new Thread(window);
t1.setName("飞猪");
t2.setName("12306");
t3.setName("携程");
t1.start();
t2.start();
t3.start();
}
}
class Window implements Runnable{
//一共有100张票
private int ticket = 100;
@Override
public void run() {
while (true) {
synchronized (this) { //this为Window对象
if (ticket > 0) {
try {
Thread.sleep(300);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖了一张票,票号为" + ticket);
ticket--;
} else {
break;
}
}
}
}
3,使用Lock锁,具体实现如下:
class Window implements Runnable{
//一共有100张票
private int ticket = 100;
//声明锁
private Lock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
lock.lock();//加锁
if (ticket > 0) {
try {
Thread.sleep(300);
System.out.println(Thread.currentThread().getName() + "卖了一张票,票号为" + ticket);
ticket--;
} catch (InterruptedException e) {
e.printStackTrace();
}finally {
lock.unlock();//释放锁
}
} else {
lock.unlock();//释放锁
break;
}
}
}
比较同步方法,同步代码块和Lock锁的区别
1,同步方法:synchronized关键字修饰的方法, 当用此关键字修饰方法时,
内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。
2,同步代码块:synchronized关键字修饰的代码块。 被该关键字修饰的语句块会自动被加上内置锁,从而实现同步。
3,一般情况下,尽量使用同步代码块,减少同步的内容。
4,Lock锁:在jdk1.5中新增了一个java.util.concurrent包来支持同步。 ReentrantLock类是可重入、互斥、实现了Lock接口的锁, 它的功能在synchronized的继承上扩展了其能力,要注意释放锁。
5,这三种方法都实现了线程的同步。