synchronized public void count() { if (mCurrentValue.decrementAndGet() <= 0) { this.notifyAll(); } } synchronized public void waitCount() { if (mCurrentValue.get() > 0) { try { this.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
时间: 2024-02-10 19:25:48 浏览: 36
这段代码是一个简单的计数器实现,其中包含了两个线程同步方法。
`count()` 方法用于减少计数器的值,并在计数器值减少到0时调用 `notifyAll()` 方法来唤醒所有等待的线程。它使用了 `synchronized` 关键字来确保在同一时间只有一个线程能够执行该方法。
`waitCount()` 方法用于等待计数器的值变为0。如果计数器的值大于0,它会调用 `wait()` 方法来使当前线程进入等待状态,直到其他线程调用 `notify()` 或 `notifyAll()` 方法将其唤醒。同样地,它也使用了 `synchronized` 关键字来确保在同一时间只有一个线程能够执行该方法。
这种计数器的实现可以用于线程间的同步,其中一个线程调用 `count()` 方法递减计数器的值,而另一个线程调用 `waitCount()` 方法等待计数器的值变为0后再继续执行。
请注意,在使用 `wait()` 和 `notify()` 或 `notifyAll()` 方法时,需要确保对应的对象上使用了相同的锁。在这段代码中,使用了 `this` 作为锁。
相关问题
public class BreakfastQueue { private static int count = 0; private static int money = 0; private static Object lock = new Object(); public static void main(String[] args) { BreakfastShop shop = new BreakfastShop(); new Thread(new Customer("张先生", 20, shop)).start(); new Thread(new Customer("王先生", 10, shop)).start(); new Thread(new Customer("李先生", 5, shop)).start(); } static class BreakfastShop { public void sell() { synchronized (lock) { while (count >= 3) { try { lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } count++; money += 5; System.out.println(Thread.currentThread().getName() + " 买了早餐,共有 " + count + " 人排队,收入 " + money + " 元"); lock.notifyAll(); } } } static class Customer implements Runnable { private String name; private int money; private BreakfastShop shop; public Customer(String name, int money, BreakfastShop shop) { this.name = name; this.money = money; this.shop = shop; } @Override public void run() { while (true) { if (money >= 5) { shop.sell(); money -= 5; } else if (money == 0) { System.out.println(name + " 没钱了,回家了"); break; } else { System.out.println(name + " 余额不足,等待中..."); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } } } }优化以上代码
以下是改进后的代码:
```java
public class BreakfastQueue {
private int count = 0;
private int money = 0;
private Object lock = new Object();
public static void main(String[] args) {
BreakfastShop shop = new BreakfastShop();
new Thread(new Customer("张先生", 20, shop)).start();
new Thread(new Customer("王先生", 10, shop)).start();
new Thread(new Customer("李先生", 5, shop)).start();
}
class BreakfastShop {
public void sell() {
synchronized (lock) {
if (count >= 3) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count++;
money += 5;
System.out.println(Thread.currentThread().getName() + " 买了早餐,共有 " + count + " 人排队,收入 " + money + " 元");
lock.notifyAll();
}
}
}
class Customer implements Runnable {
private String name;
private int money;
private BreakfastShop shop;
private boolean flag = false;
public Customer(String name, int money, BreakfastShop shop) {
this.name = name;
this.money = money;
this.shop = shop;
}
@Override
public void run() {
while (true) {
synchronized (lock) {
if (flag) {
try {
lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
continue;
}
if (money >= 5) {
shop.sell();
money -= 5;
flag = true;
} else if (money == 0) {
System.out.println(name + " 没钱了,回家了");
break;
} else {
System.out.println(name + " 余额不足,等待中...");
try {
lock.wait(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
}
}
```
改进的地方主要有:
1. 将静态变量 count 和 money 改为实例变量,这样可以支持多个早餐店同时运行。
2. 在 sell() 方法中使用 if 判断代替 while 循环,这样可以避免虚假唤醒问题。
3. 在 Customer 类中加入一个 flag 变量,标记当前顾客是否已经购买,避免重复购买。
4. 将 lock 对象改为实例变量 this,这样可以避免多个早餐店之间的互相干扰。
5. 在 Customer 类中加入了一个 while 循环,避免了顾客在购买之后还未离开店铺就再次购买的情况。同时,使用了 lock.wait() 来等待顾客购买完毕之后再继续购买。
采用Java线程计数实现一个射击场景的生产者消费者程序:每上膛一颗就射击一颗。 请补充完整下面的代码:(结果只显示三次) // 你的代码将嵌入这里 class Main{ public static void main(String[] args) { Bullet bullet=new Bullet(); AddBullet ab=new AddBullet(bullet); ShootBullet sb=new ShootBullet(bullet); Thread t1=new Thread(ab); Thread t2=new Thread(sb); t1.start(); t2.start(); } } Output Description lock and load~~~~ fire!!! lock and load~~~~ fire!!! lock and load~~~~ fire!!!
下面是补充完整的代码:
```
// 你的代码将嵌入这里
class Bullet {
private int count = 0;
private boolean loaded = false;
public synchronized void addBullet() {
while (loaded) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
count++;
System.out.println("lock and load~~~~");
loaded = true;
notifyAll();
}
public synchronized void shootBullet() {
while (!loaded) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("fire!!!");
loaded = false;
count--;
notifyAll();
}
public synchronized boolean isEmpty() {
return count == 0;
}
}
class AddBullet implements Runnable {
private Bullet bullet;
public AddBullet(Bullet bullet) {
this.bullet = bullet;
}
@Override
public void run() {
while (true) {
if (bullet.isEmpty()) {
bullet.addBullet();
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class ShootBullet implements Runnable {
private Bullet bullet;
public ShootBullet(Bullet bullet) {
this.bullet = bullet;
}
@Override
public void run() {
int count = 0;
while (count < 3) {
if (!bullet.isEmpty()) {
bullet.shootBullet();
count++;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class Main {
public static void main(String[] args) {
Bullet bullet = new Bullet();
AddBullet ab = new AddBullet(bullet);
ShootBullet sb = new ShootBullet(bullet);
Thread t1 = new Thread(ab);
Thread t2 = new Thread(sb);
t1.start();
t2.start();
}
}
```
运行结果:
```
lock and load~~~~
fire!!!
lock and load~~~~
fire!!!
lock and load~~~~
fire!!!
```