目录
四个窗口同时进行售票
利用线程进行售票处理思路:
-
利用synchronized(同步)限制进来的线程,避免出现售票异常。
-
尽量不要将synchronized放在run()上,while(true)是为了让线程一直进行循环。
class TicketRunnable implements Runnable {
private int ticket = 1000;
private int num = 0;
@Override
public void run() {
while (true) {
//synchronized (this) { //不能放在方法体上,放在方法体有一个进来要运行1000遍后才会出去
try {
Thread.sleep(new Random().nextInt(100));
boolean flag = this.sale(); //使用调用是为了观看更加方便
if(!flag){ //获取sale()的booleand值是为判断票是否售完
break; //在sale()方法内使用return;发现不能终止循环
} //应该是return不能终止不到run()内循环
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private synchronized boolean sale() {
if (ticket > 0) {
this.num++;
this.ticket--;
System.out.println(Thread.currentThread().getName() + "已售" + this.num + ",余票:" + this.ticket);
return true;
} else {
System.out.println(Thread.currentThread().getName() + "的票以买完!");
return false;
}
}
}
public class Memo01 {
public static void main(String[] args) {
TicketRunnable ticketRunnable = new TicketRunnable();
new Thread(ticketRunnable, "窗口一").start();
new Thread(ticketRunnable, "窗口二").start();
new Thread(ticketRunnable, "窗口三").start();
new Thread(ticketRunnable, "窗口四").start();
}
}
结果:
窗口二正在售票,一共已售990,余票:10
窗口三正在售票,一共已售991,余票:9
窗口一正在售票,一共已售992,余票:8
窗口二正在售票,一共已售993,余票:7
窗口四正在售票,一共已售994,余票:6
窗口二正在售票,一共已售995,余票:5
窗口一正在售票,一共已售996,余票:4
窗口三正在售票,一共已售997,余票:3
窗口二正在售票,一共已售998,余票:2
窗口四正在售票,一共已售999,余票:1
窗口二正在售票,一共已售1000,余票:0
窗口三的票以买完!
窗口一的票以买完!
窗口二的票以买完!
窗口四的票以买完!
子线程输出10次,主线程输出100次,循环运行50次
思路及步骤:
-
先理清子线程和主线程的关系,和生产者与消费者相似(我个人认为)。
-
现将子线程和主线程的输出次数先写出来 ,集中在一个类中进行调用。
子线程:
private boolean flag = true; //true表示主线程输出完毕,false表示子线程输出完毕
public synchronized void childThread() throws InterruptedException {
while (!flag) { //false表示子线程输出完毕
this.wait();
}
for (int i = 0; i < 10; i++) { //子线程循环10次,进入等待
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "****************运行******************:" + i);
}
flag = false;
this.notify();
}
主线程:
private boolean flag = true; //true表示主线程输出完毕,false表示子线程输出完毕
public synchronized void mainThread() throws InterruptedException {
while (flag) { //true表示主线程输出完毕
this.wait();
}
for (int i = 0; i < 100; i++) { //主线程循环100次,进入等待
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "---------------运行------------------:" + i);
}
flag = true;
this.notify(); //使用notify()和notifyAll()没有区别,试过
}
- 在各自的run()内进行for循环输出50次。
class ChildMessage implements Runnable {
private Message message;
public ChildMessage(Message message) {
this.message = message; //获取对象实例
}
@Override
public synchronized void run() {
for (int i = 0; i < 50; i++) { //线程循环50次
try {
this.message.childThread();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
//主线程
class MainMessage implements Runnable {
private Message message; //获取对象实例
public MainMessage(Message message) {
this.message = message;
}
@Override
public synchronized void run() {
for (int i = 0; i < 50; i++) { //线程循环50次
try {
this.message.mainThread();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Message {
private boolean flag = true; //true表示主线程输出完毕,false表示子线程输出完毕
public synchronized void childThread() throws InterruptedException {
while (!flag) { //false表示子线程输出完毕
this.wait();
}
for (int i = 0; i < 10; i++) { //子线程循环10次,进入等待
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "******运行******:" + i);
}
flag = false;
this.notify();
}
public synchronized void mainThread() throws InterruptedException {
while (flag) { //true表示主线程输出完毕
this.wait();
}
for (int i = 0; i < 100; i++) { //主线程循环100次,进入等待
Thread.sleep(100);
System.out.println(Thread.currentThread().getName() + "------运行------:" + i);
}
flag = true;
this.notify();
}
}
public class Circle {
public static void main(String[] args) {
Message message = new Message();
ChildMessage child = new ChildMessage(message);
MainMessage main = new MainMessage(message);
new Thread(child, "子线程").start();
new Thread(main, "主线程").start();
}
}
结果:
主线程------运行------:97
主线程------运行------:98
主线程------运行------:99
子线程******运行******:0
子线程******运行******:1
子线程******运行******:2
子线程******运行******:3
子线程******运行******:4
子线程******运行******:5
子线程******运行******:6
子线程******运行******:7
子线程******运行******:8
子线程******运行******:9
主线程------运行------:0
主线程------运行------:1
主线程------运行------:2
主线程------运行------:3
参考:
子线程和主线程循环输出参考处:
https://blog.csdn.net/zhaojw_420/article/details/68939728