同步线程解决售票问题:
/**
* @author WuYazhen
* @Date 2024/8/7 10:42
* 使用同步线程优化售票问题
*/
public class TicketSell {
public static void main(String[] args) {
TicketSell01 ticketSell01 = new TicketSell01();
new Thread(ticketSell01).start();
new Thread(ticketSell01).start();
new Thread(ticketSell01).start();
}
}
//实现接口方式,使用synchronized实现线程同步
class TicketSell01 implements Runnable{
private static int ticketNum = 100;
private boolean loop = true; //控制run方法while循环
public synchronized void sell(){ //同步方法,在同一个时刻只能有一个线程来执行sell方法
if (ticketNum <= 0){
System.out.println("售票结束");
loop = false;
return;
}
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("窗口"+Thread.currentThread().getName()+"售出一张票,剩余票数:"+(--ticketNum));
}
@Override
public void run() {
while (loop){
sell(); //sell方法是一个同步方法
}
}
}
线程死锁
死锁案例:
/**
* @author WuYazhen
* @Date 2024/8/10 10:28
* 模拟死锁现象
*/
public class DeadLock {
public static void main(String[] args) {
//模拟死锁现象
DeadLockDemo A = new DeadLockDemo(true);
DeadLockDemo B = new DeadLockDemo(false);
A.setName("A线程");
B.setName("B线程");
A.start();
B.start();
}
}
class DeadLockDemo extends Thread{
static Object o1 = new Object();//保证多线程,共享一个对象,这里使用static
static Object o2 = new Object();
boolean flag;
public DeadLockDemo(boolean flag){//构造器
this.flag = flag;
}
@Override
public void run() {
/*
* 业务逻辑分析:
* 1,如果flag为t,线程A就会先得到o1对象锁,然后尝试去获取o2对象锁
* 2,如果线程A得不到o2对象锁,就会Blocked
* 3,如果flag为f,线程B就会先得到o2对象锁,然后尝试去获取o1对象锁
* 4,如果线程B得不到o1对象锁,就会Blocked
* */
if (flag){
synchronized (o1){//对象互斥锁
System.out.println(Thread.currentThread().getName()+"进入1");
synchronized (o2){
System.out.println(Thread.currentThread().getName()+"进入2");
}
}
}else {
synchronized (o2){
System.out.println(Thread.currentThread().getName()+"进入3");
synchronized (o1){ //这里获取li对象的监视权
System.out.println(Thread.currentThread().getName()+"进入4");
}
}
}
}
}
运行结果显示a,b进入死锁状态
线程练习作业:
package test;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import java.util.Scanner;
/**
* @author WuYazhen
* @Date 2024/8/10 11:05
* main中启动两个线程,一个循环随机打印100以内的整数,直到第二个线程从键盘读取了“q”命令
*/
public class ThreadHomework {
public static void main(String[] args) {
M1 m1 = new M1(true);
M2 m2 = new M2(m1);
m1.start();
m2.start();
}
}
class M1 extends Thread{
private boolean b = true;
public M1(boolean b) {
this.b = b;
}
public void setB(boolean b) {
this.b = b;
}
@Override
public void run() {
Random random = new Random();
while(b){
// 生成一个1到100之间的随机整数(包含1和100)
int randomNumber = random.nextInt(100) + 1;
// 打印这个随机整数
System.out.println(randomNumber);
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class M2 extends Thread{
private M1 m1;
private Scanner scanner = new Scanner(System.in);
public M2(M1 m1) {
this.m1 = m1;
}
@Override
public void run() {
while(true){
//接收到用户的输入
System.out.println("请输入指令(Q表示退出):");
char key =scanner.next().toUpperCase().charAt(0);
if (key == 'Q'){
//已通知的方式结束A线程
m1.setB(false);
System.out.println("M2线程退出");
break;
}
}
}
}
package test;
/**
* @author WuYazhen
* @Date 2024/8/11 23:38
* 2个用户从一张10000元的卡上取钱,每次取1000,余额不足时无法取,不能出现超取现象
* 线程同步问题
*/
public class ThreadHomework02 {
public static void main(String[] args) {
TakeMoney takeMoney = new TakeMoney();
new Thread(takeMoney).start();
new Thread(takeMoney).start();
}
}
class TakeMoney implements Runnable{
private static int sum = 10000;
boolean loop = true;
public synchronized void take(){
if (sum >= 1000){
sum-=1000;
System.out.println(Thread.currentThread().getName()+"成功取钱,余额为:"+sum);
}else {
loop = false;
}
}
@Override
public void run() {
while (loop){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
take();
}
}
}