进程和线程
多线程的实现方式
多线程的实现方式
线程调度
多线程的实现方式
案例:卖票
public class SellTicketDemo {
public static void main(String[] args) {
// 创建SellTicket类的对象
SellTicket st = new SellTicket();
// 创建三个Thread类的对象,把SellTicket对象作为构造方法的参数,并给出对应的窗口名称
Thread t1 = new Thread(st, "窗口1");
Thread t2 = new Thread(st, "窗口2");
Thread t3 = new Thread(st, "窗口3");
// 启动线程
t1.start();
t2.start();
t3.start();
}
}
// 定义一个类SellTicket实现Runnable接口,里面定义一个成员变量: private int tickets = 100
public class SellTicket implements Runnable {
private int tickets = 100;
// 在SellTicket类中重写run()方法实现卖票,代码步骤如下
@Override
public void run() {
// A:判断票数大于0,就卖票,并告知是哪个窗口卖的
// B:卖了票之后,总票数要减1
// C:票没有了,也可能有人来问,所以这里用死循环让卖票的动作一直执行
while (true) {
if (tickets > 0) {
System.out.println(Thread.currentThread().getName() + "正在出售第" + tickets + "张票");
tickets--;
}
}
}
}
卖票案例的思考
一、
二、
三、
四、
五、
六、
七、
八、
九、
十、
十一、
十二、
生产者消费者案例
1. BoxDemo.java
public class BoxDemo {
public static void main(String[] args) {
// 创建奶箱对象,这是共享数据区域
Box box = new Box();
// 创建生产者对象,把奶箱对象作为构造方法参数传递,因为在这个类中要调用存储牛奶的操作
Producer producer = new Producer(box);
// 创建消费者对象,把奶箱对象作为构造方法参数传递,因为在这个类中要调用获取牛奶的操作
Customer customer = new Customer(box);
// 创建2个线程对象,分别把生产者对象和消费者对象作为构造方法参数传递
Thread thread1 = new Thread(producer);
Thread thread2 = new Thread(customer);
// 启动线程
thread1.start();
thread2.start();
}
}
2. Box.java
// 奶箱类(Box):定义一个成员变量,表示第x瓶奶,提供存储牛奶和获取牛奶的操作
public class Box {
// 定义一个成员变量,表示第x瓶奶
private int milk;
// 定义一个成员变量,表示奶箱的状态
private boolean state = false;
// 提供存储牛奶和获取牛奶的操作
public synchronized void put(int milk){
if (state) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.milk = milk;
System.out.println("送奶工将第" + this.milk + "瓶奶放入奶箱");
// 生产完毕之后,修改奶箱状态
state = true;
// 唤醒其他等待的线程
notifyAll();
}
public synchronized void get() {
// 如果没有牛奶,等待生产
if (!state) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 如果有牛奶,就消费牛奶
System.out.println("用户拿到第" + this.milk + "瓶奶");
// 消费完毕之后,修改奶箱状态
state = false;
// 唤醒其他等待的线程
notifyAll();
}
}
3. Producer.java
// 生产者类(Producer):实现Runnable接口,重写run)方法,调用存储牛奶的操作
public class Producer implements Runnable {
private Box box;
public Producer(Box box) {
this.box = box;
}
@Override
public void run() {
for (int i = 1; i <= 31; i++) {
box.put(i);
}
}
}
4. Customer.java
// 消费者类(Customer):实现Runnable接口,重写run()方法,调用获取牛奶的操作
public class Customer implements Runnable {
private Box box;
public Customer(Box box) {
this.box = box;
}
@Override
public void run() {
while (true) {
box.get();
}
}
}