【线程实现的两种方式及区别】
2021-07-09 14:06
标签:end ati vat 操作 [] name main cpu err 我们来用最经典的卖票的案例,表明两种实现方式的区别,同时分析线程不安全产生的原因 一、继承Thread类 二、实现Runnable接口 启动线程 可以看到,二者的主要区别是: 1.实现Runnable接口的方式可以避免由于JAVA单继承带来局限性 2.实现Runnable接口的方式,适用多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码、数据有效分离,较好的体现了面向对象的设计思想。 加上每次卖票延迟200毫秒,运行程序,发现两个问题: A:相同的票卖了多次:CPU的一次操作必须是原子性 B:出现了负数票:随机性和延迟导致的 【线程实现的两种方式及区别】 标签:end ati vat 操作 [] name main cpu err 原文地址:https://www.cnblogs.com/zuixinxian/p/9565888.htmlpackage test;
/**
* @Description
* @Author shusheng
* @Email shusheng@yiji.com
* @Date 2018/8/31
*/
public class SellTicketOne extends Thread{
private static int tickets = 100;
@Override
public void run(){
while(true){
if(tickets>0){
System.out.println(getName()+"正在出售第"+tickets+"张票");
tickets--;
}
}
}
}
package test;
/**
* @Description
* @Author shusheng
* @Email shusheng@yiji.com
* @Date 2018/8/31
*/
public class SellTicketTwo implements Runnable{
private static int tickets = 100;
@Override
public void run(){
while(true){
if(tickets>0){
System.out.println(Thread.currentThread().getName()+"正在出售第"+tickets+"张票");
tickets--;
}
}
}
}
package test;
/**
* @Description
* @Author shusheng
* @Email shusheng@yiji.com
* @Date 2018/8/31
*/
public class SellTicketTest {
public static void main(String[] args) {
SellTicketOne one1 = new SellTicketOne();
SellTicketOne one2 = new SellTicketOne();
SellTicketOne one3 = new SellTicketOne();
one1.setName("窗口一");
one2.setName("窗口二");
one3.setName("窗口三");
one1.start();
one2.start();
one3.start();
SellTicketTwo two = new SellTicketTwo();
Thread t1 = new Thread(two,"窗口四");
Thread t2 = new Thread(two,"窗口五");
Thread t3 = new Thread(two,"窗口六");
t1.start();
t2.start();
t3.start();
}
}