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; }
*
*
*/
}
线程的同步(synchronized关键字)
最新推荐文章于 2024-07-13 19:55:31 发布