实现Runnbale接口使用synchronized
package tickets;
public class SaleTicket01 implements Runnable{
public int count = 0;
public int total = 10000;
public void run(){
while(total > 0){
synchronized(this){
if(total > 0){
--total;
++count;
System.out.println(Thread.currentThread().getName() + "已经售出了第" + count + "\t张票");
}
}
}
}
public static void main(String[] args){
SaleTicket01 saleTicket01 = new SaleTicket01();
for(int i = 0; i < 5; i++){
new Thread(saleTicket01,"" + i).start();
}
}
}
继承Thread类使用synchronized
因为是继承的Thread类,因此票数total要写成static,这样的话这个total就属于类而不属于对象了。
package tickets;
public class SaleTicket02 extends Thread
{
public static int total = 10;
public static int count = 0;
public void run()
{
while (true)
{
synchronized (this)
{
if (total > 0)
{
--total;
++count;
System.out.println(Thread.currentThread().getName() + "\t 卖出的第" + count + "\t张票");
}
else
{
break;
}
}
}
}
public static void main(String[] args)
{
SaleTicket02 saleTicket1 = new SaleTicket02();
saleTicket1.start();
SaleTicket02 saleTicket2 = new SaleTicket02();
saleTicket2.start();
}
}
实现Runnable并使用Lock
要注意在while循环中,先解锁了之后再判断是否可以退出,不然就算ticket<0的时候,break也是被锁住不可以退出的。
package tickets;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
public class Saleticket03 implements Runnable
{
public int ticket = 10;
public int count = 0;
private Lock lock = new ReentrantLock();
@Override
public void run()
{
while (true)
{
lock.lock();
if (ticket > 0)
{
--ticket;
++count;
System.out.println(Thread.currentThread().getName() + "\t卖出的第" + count + "\t\t\t张票");
}
lock.unlock();
//这里不可以写在unlock前面,不然不可以退出循环
if (ticket <= 0)
{
break;
}
}
}
public static void main(String[] args)
{
Saleticket03 saleticket03 = new Saleticket03();
Thread t1 = new Thread(saleticket03, "窗口一");
Thread t2 = new Thread(saleticket03, "窗口二");
Thread t3 = new Thread(saleticket03, "窗口三");
t1.start();
t2.start();
t3.start();
}
}
注意:如果该类继承了Thread类,那么在重写的run方法中使用lock则会出现逻辑问题,推荐使用synchronized!