Chinaunix首页 | 论坛 | 博客
  • 博客访问: 4447224
  • 博文数量: 1214
  • 博客积分: 13195
  • 博客等级: 上将
  • 技术积分: 9105
  • 用 户 组: 普通用户
  • 注册时间: 2007-01-19 14:41
个人简介

C++,python,热爱算法和机器学习

文章分类

全部博文(1214)

文章存档

2021年(13)

2020年(49)

2019年(14)

2018年(27)

2017年(69)

2016年(100)

2015年(106)

2014年(240)

2013年(5)

2012年(193)

2011年(155)

2010年(93)

2009年(62)

2008年(51)

2007年(37)

分类: Java

2017-09-30 17:24:48

原文:http://www.cnblogs.com/200911/p/3894613.html

总结:实现Runnable接口比继承Thread类更有优势:

1.因为java只能单继承,实现Runnable接口可以避免单继承的局限性

2.继承Thread类,多个线程不能处理或者共享同一个资源,但是实现Runnable接口可以处理同一个资源。

下面我们做个测试:验证下。车站的售票系统售票的例子,车站的各个售票口相当于各个线程,我们先使用第一种方法几继承Thread类的方式实现:

代码如下:

 

复制代码
package com.lp.ecjtu.Thread; /** * 
 * @author Administrator
 * 车站的售票系统售票的例子,车站的各个售票口相当于各个线程。
 * */ public class TicketsThread extends Thread{ //用静态变量存放这100张票,这样就不会卖重复 private int tickets = 100; public void run(){ while(true){ if(tickets > 0){
                System.out.println(Thread.currentThread().getName()+"***sale***"+(--tickets));
            }
        }
    } /** * @param args */ public static void main(String[] args) { // 不合理的买票程序,因为,不同线程都可以卖同一张票, //现实生活中不是这样的,窗口1买完第99张票,窗口2不可以卖了。 TicketsThread t1 = new TicketsThread();
        TicketsThread t2 = new TicketsThread();
        TicketsThread t3 = new TicketsThread();
        t1.start();
        t2.start();
        t3.start();
    }

}
复制代码

代码的原理图如下:

 

总结:不合理的卖票方法,不同线程都可以卖同一张票,现实生活中不是这样的,窗口1卖完99号票,窗口2就不可以再卖这张票了。

怎么解决呢?使用实现Runnable接口的方法就可以解决,代码如下:

 

 

复制代码
public class TicketsRunnable implements Runnable { private int ticket=100; //Object obj = new Object(); public TicketsRunnable(){
        System.out.println("*****************************");
    }
    @Override public void run() { // TODO Auto-generated method stub while(true){ //synchronized(obj){ //同步代码块 if(ticket > 0){//当线程0被调起的时候,当执行到这条判断语句的时候,线程1被调起抢了CPU资源,线程0进入冻结状态。 try {
                        Thread.sleep(100);//中断当前活跃的线程,或者执行的线程 } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName()+"正在卖票"+ticket--); //System.out.println(Thread.currentThread().getId()); //System.out.println(Thread.currentThread().getName());  } //}  }
    } /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub TicketsRunnable runna = new TicketsRunnable();
        Thread t1 = new Thread(runna);
        Thread t2 = new Thread(runna);
        Thread t3 = new Thread(runna);  t1.start();
        t2.start();
        t3.start();  }

}
复制代码

 

 

 

上面代码简单内存图理解如下:

总结:三个窗口再卖100张票,直到卖完,3个线程才停止。卖的票的号码没有重复,真正实现了现实生活中的卖票的效果。但是存在一个线程安全问题,通过测试运行发现,打印出了0,-1,-2等错票,多线程运行出现了安全问题,这就需要引入线程锁机制,下一篇博客详细的讲解怎样避免这一问题。

阅读(452) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~