Java之多线程-同步代码块

线程同步

Java中提供了线程同步的机制,来解决上述的线程安全问题。

Java中实现线程同步,主要借助synchronized关键字实现。

线程同步方式:

  • 同步代码块

  • 同步方法

  • 锁机制

1)同步代码块

格式:

//Object类及其子类对象都可以作为 线程同步锁对象 使用
synchronized(mutex锁对象) {
    //需要同步操作的代码
    //...
}

案例:

​ 使用线程同步代码块,解决上述案例Bug

package com.briup.chap10;

class TicketRunnable2 implements Runnable {
	//待售票数量
	private int num = 50;
	
	//准备锁对象【多个线程必须使用相同锁对象】
	Object mutex = new Object();
	
	@Override
	public void run() {
		while(true) {
			//同步代码块:固定书写格式,需要使用同一把锁
            //线程执行流程:
            //	1.线程成功抢占到共享资源mutex(上锁成功),才能进入代码块执行
            //	  其他抢占资源失败的线程,则进入阻塞状态
            //	2.同步代码执行完成,该线程自动释放共享资源(解锁)
            //	  其他线程由阻塞转入就绪状态,重新抢占资源(上锁)
			synchronized (mutex) {
				//如果待售数量 小于0,跳出循环,线程结束
				if(num <= 0)
					break;
				
				//输出信息:模拟卖票
				String name = Thread.currentThread().getName();
				System.out.println(name + " 正在卖票,编号:" + num);
				
				//编号自减
				num--;
				
				//每隔50ms 销售 一张票【sleep放下面是为了更好的输出效果】
				try {
					Thread.sleep(50);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}
	}
}

public class Test16_CodeBlock {
	public static void main(String[] args) {
		Runnable r = new TicketRunnable2();
		
		Thread t1 = new Thread(r,"1号窗口");
		Thread t2 = new Thread(r,"2号窗口");
		Thread t3 = new Thread(r,"3号窗口");
		
		t1.start();
		t2.start();
		t3.start();
	}
}

注意,要实现线程同步,必须满足下面2个条件:

  • 所有线程都需要参与线程同步
  • 所有线程必须使用同一个锁对象

运行效果:

在这里插入图片描述

多次运行,观察效果可知,之前的2个问题都已经成功解决!

线程同步理解:

//线程只有竞争到锁,才能执行同步代码块中代码(上锁)
synchronized(mutex锁对象) {
    需要同步操作的代码

	//程序执行流程离开该代码块,则自动释放锁(解锁)
    //离开含多种情况,正常出右大括号,break、return或遇到异常跳出
}

线程同步可理解成一个规则(进卫生间必须竞争到钥匙开门,离开卫生间必须锁门交出钥匙)

  • 所有的线程都遵循这种规则,才能同步成功

  • 如果个别线程不遵循规则(不用钥匙,翻窗进入),则无法实现同步

锁对象可以理解成保证线程同步的重要因素(打开卫生间门的唯一钥匙)

  • 多个线程使用同一把锁(用唯一的钥匙开门),才能保证线程同步

  • 如果使用不同的锁(不同的人用不同的钥匙去开门),则也无法实现线程同步效果

线程状态图为:

在这里插入图片描述

  • 11
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值