黑马程序员——多线程之卖票问题

来源:互联网 发布:人体 3d 软件 编辑:程序博客网 时间:2024/05/23 15:42

------- android培训、java培训、期待与您交流! ----------

需求 :简单的卖票程序
多个窗口卖票

创建线程的第二种方法:实现Runable接口
步骤:
1,定义类实现Runable接口
2,覆盖Runable接口中的方法
将线程要运行的代码存放在该run方法中
3,通过Thread类建立线程对象
4,将Runable接口的子类对象作为实际参数传递给Thread类的构造函数
为什么要将Runable接口的子类对象传递给Thread的构造函数
因为,自定义的run方法所属的对象是Runable接口的子类对象
所以要让线程去指定对象的run方法,就必须明确该run方法所属的对象
5,调用Thread类的start方式开启线程并调用Runable接口子类的run方法
实现方法和继承方式有什么区别?
实现方式的好处:避免了单继承的局限性
在定义线程时:建立使用实现方式
继承Thread:线程代码存放Thread子类run方法中
实现Runnable:线程代码存放在接口的子类的run方法


class Ticket implements Runnable //extends Thread
{
private int tick = 100;
public void run()
{
while(true)
{
if(tick>0)
{
System.out.println(Thread.currentThread().getName()+"sale......"+tick--);
}
}
}
}


public class TicketDemo {


public static void main(String[] args) 
{
// Ticket t1 = new Ticket();
// Ticket t2 = new Ticket();
// Ticket t3 = new Ticket();
// Ticket t4 = new Ticket();
// t1.start();
// t1.start();
// t1.start();
// t1.start();

Ticket t = new Ticket();

Thread t1 = new Thread(t);//创建了一个线程
Thread t2 = new Thread(t);//创建了一个线程
Thread t3 = new Thread(t);//创建了一个线程
Thread t4 = new Thread(t);//创建了一个线程

t1.start();
t2.start();
t3.start();
t4.start();
}
}

通过分析,发现,打印0,-1,-2等错票

多线程的运行出现了问题

问题的原因:
当多条语句在操作同一个线程共享数据时,一个线程对多条语句只执行了一部分,还没执行完
另一个线程参与进来执行,导致共享数据的错误

解决办法:
对多条操作共享数据的语句,只能让一个线程都执行完成,在执行过程中其他线程不可以参与执行

java对于多线程的安全问题提供了专业的解决方式

就是同步代码块

synchronized(对象)
{
需要被同步的代码
}

对象如同锁,持有锁的现成可以在同步中执行
没有持有锁的线程即使获取cpu的执行权,也进不去,因为没有获取锁

同步的前提:
1,必须要有两个或者两个以上的线程
2,必须是多个线程使用同一个锁
3,必须保证同步中只能有一个线程在运行

好处:解决了多线程的安全问题

弊端:多个线程需要判断锁,较为消耗资源

class  Ticket2 implements Runnable 
{
private int tick = 100;
Object obj = new Object();
public void run()
{
while(true)
{
synchronized(obj)
{
if(tick>0)
{
try
{
   Thread.sleep(10);
}
catch(Exception e){}
System.out.println(Thread.currentThread().getName()+"sale......"+tick--);
}
}
}
}
}


public class TicketDemo2 {


public static void main(String[] args) 
{


Ticket2 t = new Ticket2();

Thread t1 = new Thread(t);//创建了一个线程
Thread t2 = new Thread(t);//创建了一个线程
Thread t3 = new Thread(t);//创建了一个线程
Thread t4 = new Thread(t);//创建了一个线程

t1.start();
t2.start();
t3.start();
t4.start();
}


}

0 0