多个线程访问共享数据就会产生冲突的问题,以卖票为例,多个窗口卖同一批票就会出现重复卖的问题
public static void main(String[] args) {
Runnable runnable = new Runnable() {
Integer tickets = 100;
@Override
public void run() {
String name = Thread.currentThread().getName();
while(tickets-- > 0) {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name + "正在卖票: " + tickets);
}
}
};
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
}
解决方案一:使用同步机制,共享部分同步执行则不会出现重复操作问题
synchronized
关键字实现代码块同步public static void main(String[] args) { Object lock = new Object(); Runnable runnable = new Runnable() { Integer tickets = 100; @Override public void run() { String name = Thread.currentThread().getName(); while (true) { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } synchronized (lock) { if (tickets <= 0) break; System.out.println(name + "正在卖票: " + tickets); tickets--; } } } }; new Thread(runnable).start(); new Thread(runnable).start(); new Thread(runnable).start(); }
synchronized
同步方法实现同步机制static Integer tickets = 100; public static void main(String[] args) { Runnable runnable = new Runnable() { @Override public void run() { while (true) { try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } sellTicked(); if (tickets <= 0) break; } } }; new Thread(runnable).start(); new Thread(runnable).start(); new Thread(runnable).start(); } synchronized private static void sellTicked() { if (tickets <= 0) return; String name = Thread.currentThread().getName(); System.out.println(name + "正在卖票: " + tickets); tickets--; }
解决方案二:使用锁,ReentrantLock
public class LockDemo {
static Integer tickets = 100;
public static void main(String[] args) {
Runnable run = new Runnable() {
ReentrantLock lock = new ReentrantLock();
@Override
public void run() {
while(tickets > 0) {
try {
Thread.sleep(1);
}catch(Exception e) {
}
lock.lock();
sellTickets();
lock.unlock();
}
}
};
new Thread(run).start();
new Thread(run).start();
new Thread(run).start();
}
private static void sellTickets() {
String threadName = Thread.currentThread().getName();
if (tickets < 0) return;
System.out.println(threadName + "正在卖第" + tickets + "张票");
tickets--;
}
}