线程的同步(synchronized关键字)

本文通过一个火车票售票系统的实例,详细介绍了如何使用Java的synchronized关键字来确保多线程环境下的数据一致性。文章重点讲解了同步方法和同步代码块的运用,并通过具体代码演示了如何避免线程冲突。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

package com.mipo.thread;

/**
 * 线程的同步 大多数需要运行多线程的应用程序中,两个或多个线程需要共享对同一个数据的访问。
 * 如果每个线程都会调用一个修改该数据状态的方法,那么这些线程将会互相影响对方的运行。
 * 为了避免多个线程同时访问一个共享数据,可以通过关键字synchronized来加保护伞,保证数据的安全
 * synchronized主要运用于同步代码块和同步方法中。
 * 
 * @author Administrator
 *
 */
public class ThreadTest3 {

	// 有一火车票售票系统,它有5个售票点,共同销售100张火车票。用多线程来模拟这个销售系统
	public static void main(String[] args) {
		TicketOffice to = new TicketOffice();
		
		Thread t1 = new Thread(to);// 创建线程
		t1.setName("售票点1");// 设置线程名
		t1.start();
		Thread t2 = new Thread(to);// 创建线程
		t2.setName("售票点2");// 设置线程名
		t2.start();
		Thread t3 = new Thread(to);// 创建线程
		t3.setName("售票点3");// 设置线程名
		t3.start();
		Thread t4 = new Thread(to);// 创建线程
		t4.setName("售票点4");// 设置线程名
		t4.start();
		Thread t5 = new Thread(to);// 创建线程
		t5.setName("售票点5");// 设置线程名
		t5.start();

	}

}

//该类只能实现Runnable接口,而不能继承Thread类(此方法在创建线程时要创建多个对象,会出问题)
class TicketOffice implements Runnable {
	private int tickets = 0;// 火车票计数器--成员变量

	public void run() {
		boolean flag = true;// 是否还有票可卖--局部变量
		while (flag) {
			flag = sell();// 售票
		}
	}

	// 同步方法:synchronized放在方法声明中,表示整个方法为同步方法
	public synchronized boolean sell() {// 售票方法:返回值表示是否还有票可卖
		boolean flag = true;

		if (tickets < 100) {
			tickets = tickets + 1;// 更改票数
			System.out.println(Thread.currentThread().getName() + ":卖出第" + tickets + "张票");
		} else {
			flag = false;
		}

		// 为了增大出错几率,让线程睡眠15毫秒
		try {
			Thread.sleep(15);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		return flag;
	}

	// 同步代码块:把线程体内执行的方法中会操作到共享数据的语句封装在"{}"之内,
	// 然后用synchronized放在某个对象前面修饰这个代码块
	// 这种情况下,只是同步了会操作到共享数据的代码,比同步整个方法会更有效率
	/*
	 * public boolean sell() {//售票方法:返回值表示是否还有票可卖 boolean flag = true;
	 * synchronized(this) { if (tickets < 100) { tickets = tickets + 1;//更改票数
	 * System.out.println(Thread.currentThread().getName()+ ":卖出第"+tickets+"张票"
	 * ); }else { flag = false; } }
	 * 
	 * 
	 * 
	 * //为了增大出错几率,让线程睡眠15毫秒 try { sleep(15); } catch (InterruptedException e) {
	 * e.printStackTrace(); } return flag; }
	 * 
	 * 
	 */
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值