// 购票类
public class Java04 implements Runnable {
int count = 1;
public static void main(String[] args) {
// 多线程并发的问题
// 运行机制:默认单例多线程机制、只有一个对象、开启多个线程和用户交互。(数据库:并发事务)
// 线程A ->
// 12306火车票购票
// 线程B ->
// 处理多线程并发问题:两种方式
// 原因:多个线程同时访问了一个方法、同时访问一个代码片段。
// 解决:某一个时刻只让一个线程访问、多个线程排队访问、效率低、但是安全。并发量大的时候考虑解决线程安全问题。
// 同步块:使用synchronized关键字锁定一个对象、把可能出现并发问题的代码放入同步块中。确保每次只有一个线程访问。
// 同步方法:使用synchronized关键字修饰方法、让整个方法的实现都是线程安全的。
Java04 x = new Java04();
Thread a = new Thread(x, "线程A");
a.start();
Thread b = new Thread(x, "线程B");
b.start();
// 同步方法:并发量大的时候可以保证线程安全:某一个时刻只有一个线程访问此方法
// 锁机制:同步方法锁的是类对象(Java04.class)
// 原理:当线程访问同步方法的时候、先检查类对象是否加锁
// 如果类对象没有加锁:可以访问方法、并对类对象加锁、其它线程在方法外排队等候
// 如果类对象已经加锁:在外边排队等候、等方法中线程调用结束之后释放锁才能访问。
public synchronized void m() {
// (1)线程B先启动:
// (3)线程A启动
String s = "";
// 同步块
// 原理:在Java语言中、每一个对象都有一个锁机制
// 当线程访问同步块的时候、先检查对象是否被加锁、如果没有锁则可以访问同步块代码、同时给对象加锁。
// 当前后续线程访问同步块的时候、发现对象已经被加锁、只能在外等候、等待里边线程访问完同步块后释放锁才能访问。
// synchronized (s) {
if (count > 0) {
// (2)线程B:休眠1秒
// (4)线程A:休眠1秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(Thread.currentThread().getName());
count--;
System.out.println(count);
@Override
public void run() {
while (true) {
// 注意:不能用Integer锁对象。
String s = "";
synchronized (s) {
if (count > 0) {
// (2)线程B:休眠1秒
// (4)线程A:休眠1秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println(Thread.currentThread().getName());
count--;
System.out.println(count);
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.