文章里借鉴了--https://www.cnblogs.com/pureEve/p/6524366.html这篇文章里的内容
1、线程继承thred类,并重写,然后出现异步的情况。
public class ThreadTest extends Thread
{
//通过构造方法给线程名字赋值
public ThreadTest (String name){
super(name);//给线程名字赋值
}
//为了保持数量的一直,票数设置为静态
static int tick=20;
//重写run方法,实现买票操作
@Override
public void run() {
// TODO Auto-generated method stub
while(tick>0){
if(tick>0){
//getName()获取线程类的名字
System.out.println(getName()+"卖出了第"+tick+"张票");
tick--;
}else{
System.out.println("票卖完了");
}
try{
sleep(1000);//休息一秒
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
然后用方法类对这个线程进行调用
public class MianClass
{
public static void main(String[] args) {
//实例化站台对象,并为每一个站台取名字
ThredTest thredTest1=new ThredTest("窗口1");
ThredTest thredTest2=new ThredTest("窗口2");
ThredTest thredTest3=new ThredTest("窗口3");
//同时开启三个线程
thredTest1.start();
thredTest2.start();
thredTest3.start();
}
}
线程调用的方式如下:哪个线程先抢到资源,哪个线程就先跑。从第17张票开始,窗口二先抢到了资源,并开始输出,输出之后,还没来得及执行--的操作,然后窗口一就抢到了资源,并开始输出。导致了异常的情况。如果效果不明显,可以将循环的数值调大。
2、当给线程加上同步锁
public class ThredTest extends Thread
{
//通过构造方法给线程名字赋值
public ThredTest(String name){
super(name);//给线程名字赋值
}
//为了保持数量的一直,票数设置为静态
static int tick=20;
//创建一个静态钥匙
static Object ob="aa";
//重写run方法,实现买票操作
@Override
public void run() {
// TODO Auto-generated method stub
while(tick>0){
synchronized(ob){//这个很重要,必须使用一个锁
//进去的人会把钥匙拿在手上,出来后才把钥匙拿让出来
if(tick>0){
System.out.println(getName()+"卖出了第"+tick+"张票");
tick--;
}else{
System.out.println("票卖完了");
}
}
try{
sleep(1000);//休息一秒
}catch(InterruptedException e){
e.printStackTrace();
}
}
}
}
再次用同意的方法类调用线程。加上锁之后。每当调用这个线程,必须等执行完同步锁里的方法,才能释放资源让下一个线程调用。