java多线程的开发有两种方法:

(1)实现Runnable接口;

(2)继承Thread类;

区别:

(1)由于java中一个类只能继承一个父类,但是可以实现多个接口,所以实现Runnable接口比继承Thread更灵活。

(2)实现Runnable接口,最终还是要用Thread(Runnable)、Thread(Runnable,String)等构造函数调用,但是此时可以多个Thread共用一个Runnable,实现资源共享(详见后面售票的实例),当然也可以使用不同的Runnable(详见后面人与叉子的实例),从这点看实现Runnable接口也比继承Thread类更灵活。

联系:

Thread类其内部实现如下:

public class Thread extends Object implements Runnable,可以看出Thread类也是Runnable接口的子类;

实例1:售票问题,假设现在有三个窗口进行售票(并发执行)。

用实现Runnable接口的方法实现代码如下:

  1. package ticket2;
  2.  
  3. public class ticket2
  4. {
  5. public static void main(String []args)
  6. {
  7. Show_tickets show_ticket=new Show_tickets();
  8. new Thread(show_ticket,"windows1").start();
  9. new Thread(show_ticket,"windows2").start();
  10. new Thread(show_ticket,"windows3").start();
  11. }
  12. }
  13. class Show_tickets implements Runnable
  14. {
  15. private int tickets=10;
  16. public void run()
  17. {
  18. while(true)
  19. {
  20. if(tickets>0)
  21. {
  22. System.out.println(Thread.currentThread().getName()+" showed the ticket"+tickets--);
  23. try {
  24. Thread.sleep(1000);
  25. } catch (InterruptedException e) {
  26. // TODO Auto-generated catch block
  27. e.printStackTrace();
  28. }
  29. }
  30. else
  31. {
  32. break;
  33. }
  34. }
  35. }
  36. }

执行结果:

windows1 showed the ticket10
windows2 showed the ticket9
windows3 showed the ticket8
windows2 showed the ticket7
windows1 showed the ticket6
windows3 showed the ticket5
windows1 showed the ticket4
windows2 showed the ticket3
windows3 showed the ticket2
windows2 showed the ticket1

用继承Thread实现如下:

  1. package ticket1;
  2.  
  3. public class ticket1
  4. {
  5. public static void main(String []args)
  6. {
  7. new Show_tickets("window1").start();
  8. new Show_tickets("window2").start();
  9. new Show_tickets("window3").start();
  10. }
  11. }
  12.  
  13. class Show_tickets extends Thread
  14. {
  15. private int tickets=10;
  16. private String name;
  17. Show_tickets(String sname)
  18. {
  19. this.name=sname;
  20. }
  21. public void run()
  22. {
  23. while(true)
  24. {
  25. if(tickets>0)
  26. {
  27. System.out.println(name+" showed the ticket"+tickets-- );
  28. try {
  29. Thread.sleep(1000);
  30. } catch (InterruptedException e) {
  31. // TODO Auto-generated catch block
  32. e.printStackTrace();
  33. }
  34. }
  35. else
  36. {
  37. break;
  38. }
  39. }
  40. }
  41. }

执行结果如下:

window1 showed the ticket10
window2 showed the ticket10
window3 showed the ticket10
window3 showed the ticket9
window2 showed the ticket9
window1 showed the ticket9
window1 showed the ticket8
window2 showed the ticket8
window3 showed the ticket8
window3 showed the ticket7
window2 showed the ticket7
window1 showed the ticket7
window1 showed the ticket6
window2 showed the ticket6
window3 showed the ticket6
window3 showed the ticket5
window2 showed the ticket5
window1 showed the ticket5
window1 showed the ticket4
window2 showed the ticket4
window3 showed the ticket4
window3 showed the ticket3
window2 showed the ticket3
window1 showed the ticket3
window1 showed the ticket2
window2 showed the ticket2
window3 showed the ticket2
window3 showed the ticket1
window2 showed the ticket1
window1 showed the ticket1

可见由于方法1中Show_tickets类是被实例化之后,给三个进程共用的,所以相当于3个窗口一共有10张票大家来卖,而方法2中由于每一个Show_tickets都被实例化为一个对象,所以其中的变量tickets也就是独立的,相当于每一个窗口都有10张票。(当然方法2中也可以用static实现共享)

实例2 人和叉子的问题,有5个人,5个叉,他们围城一圈,叉子依次摆在他们相邻的地方,只有一个人的左右手边叉子都没被用的时候,这个人才拿起叉子(左右2个都被拿起)吃饭,吃完后1秒,将叉子放下,若每个人吃一次之后就不再吃了,模仿他们吃饭的顺序。

用实现Runnable接口的方法实现代码如下:

  1. package person1;
  2.  
  3. public class personfork
  4. {
  5. public static void main(String []args)
  6. {
  7. Forks fork=new Forks();
  8. Person person1=new Person("person1",fork);
  9. new Thread(person1,"0").start();;
  10. Person person2=new Person("person2",fork);
  11. new Thread(person2,"1").start();
  12. Person person3=new Person("person3",fork);
  13. new Thread(person3,"2").start();
  14. Person person4=new Person("person4",fork);
  15. new Thread(person4,"3").start();
  16. Person person5=new Person("person5",fork);
  17. new Thread(person5,"4").start();
  18. }
  19. }
  20.  
  21. class Person implements Runnable
  22. {
  23. private String person_name;
  24. private Forks fork;
  25. Person(String name,Forks fork_input)
  26. {
  27. this.person_name=name;
  28. this.fork=fork_input;
  29. }
  30. public void run()
  31. {
  32. fork.get_fork();
  33. System.out.println("i am eating " + person_name);
  34. try
  35. {
  36. Thread.sleep(1000);
  37. } catch (InterruptedException e)
  38. {
  39. // TODO Auto-generated catch block
  40. e.printStackTrace();
  41. }
  42. fork.put_fork();
  43. }
  44. }
  45. class Forks
  46. {
  47. private int forks[]={0,0,0,0,0};
  48. public synchronized void get_fork()
  49. {
  50. String thread_name=Thread.currentThread().getName();
  51. int num=Integer.parseInt(thread_name);
  52. while(1 == forks[num] || 1 == forks[(num+1)%5])
  53. {
  54. try
  55. {
  56. wait();
  57. } catch (InterruptedException e)
  58. {
  59. // TODO Auto-generated catch block
  60. e.printStackTrace();
  61. }
  62. }
  63. forks[num]=1;
  64. forks[(num+1)%5]=1;
  65. }
  66. public synchronized void put_fork()
  67. {
  68. String thread_name=Thread.currentThread().getName();
  69. int num=Integer.parseInt(thread_name);
  70. forks[num]=0;
  71. forks[(num+1)%5]=0;
  72. notifyAll();
  73. }
  74. }

用继承Thread实现如下:

  1. package personfork;
  2.  
  3. public class personfork
  4. {
  5. public static void main(String []args)
  6. {
  7. Fork fork=new Fork();
  8. new Person("person1","0",fork).start();
  9. new Person("person2","1",fork).start();
  10. new Person("person3","2",fork).start();
  11. new Person("person4","3",fork).start();
  12. new Person("person5","4",fork).start();
  13. }
  14. }
  15.  
  16. class Person extends Thread
  17. {
  18. private String person_name;
  19. //private String thread_name;
  20. private Fork fork;
  21. Person(String person_name1,String thread_name1,Fork fork1)
  22. {
  23. super(thread_name1);
  24. //person_name=person_name1;
  25. //fork=fork1;
  26. this.person_name=person_name1;
  27. this.fork=fork1;
  28. }
  29. public void run()
  30. {
  31. //System.out.println("I am Eating:"+person_name);
  32. fork.get_fork();
  33. System.out.println("I am Eating:"+person_name);
  34. try {
  35. sleep(1000);
  36. } catch (InterruptedException e) {
  37. // TODO Auto-generated catch block
  38. e.printStackTrace();
  39. }
  40. fork.put_fork();
  41. }
  42. }
  43. class Fork
  44. {
  45. private int forks []={0,0,0,0,0};
  46. public synchronized void get_fork()
  47. {
  48. int num=Integer.parseInt(Thread.currentThread().getName());
  49. while(1==forks[num] || 1==forks[(num+1)%5])
  50. {
  51. try {
  52. wait();
  53. } catch (InterruptedException e) {
  54. // TODO Auto-generated catch block
  55. e.printStackTrace();
  56. }
  57. }
  58. forks[num]=1;
  59. forks[(num+1)%5]=1;
  60. }
  61. public synchronized void put_fork()
  62. {
  63. int num=Integer.parseInt(Thread.currentThread().getName());
  64. forks[num]=0;
  65. forks[(num+1)%5]=0;
  66. notifyAll();//唤醒其他线程
  67. }
  68. }

两种方法的结果一样基本都是5个人随机吃一遍,这里的Person是不同的5个人,所以在实现Runnable接口的方法中也并没有将其共享资源,而是放到5个不同的线程中。

java多线程(内附实例:窗口售票问题、人和叉子的问题)的更多相关文章

  1. java多线程的编程实例

    java中可有两种方式实现多线程: 一种是继承Thread类: 一种是实现Runnable接口: Thread类 是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的ru ...

  2. java多线程找素数实例

    package ltb20180106; public class FindPrime implements Runnable{ private int prime; private int q; p ...

  3. Java基础 继承的方式创建多线程 / 线程模拟模拟火车站开启三个窗口售票

    继承的方式创建多线程 笔记: /**继承的方式创建多线程 * 线程的创建方法: * 1.创建一个继承于Thread 的子类 * 2.重写Thread类的run()方法 ,方法内实现此子线程 要完成的功 ...

  4. java多线程编程实例

    [转]这篇文章主要介绍了java多线程编程实例,分享了几则多线程的实例代码,具有一定参考价值,加深多线程编程的理解还是很有帮助的,需要的朋友可以参考下. 1.三个售票窗口同时出售20张票程序分析:   ...

  5. Java经典设计模式之七大结构型模式(附实例和详解)

    博主在大三的时候有上过设计模式这一门课,但是当时很多都基本没有听懂,重点是也没有细听,因为觉得没什么卵用,硬是要搞那么复杂干嘛.因此设计模式建议工作半年以上的猿友阅读起来才会理解的比较深刻.当然,你没 ...

  6. Java设计模式之七大结构型模式(附实例和详解)

    博主在大三的时候有上过设计模式这一门课,但是当时很多都基本没有听懂,重点是也没有细听,因为觉得没什么卵用,硬是要搞那么复杂干嘛.因此设计模式建议工作半年以上的猿友阅读起来才会理解的比较深刻.当然,你没 ...

  7. (转)Java经典设计模式(2):七大结构型模式(附实例和详解)

    原文出处: 小宝鸽 总体来说设计模式分为三大类:创建型模式.结构型模式和行为型模式. 博主的上一篇文章已经提到过创建型模式,此外该文章还有设计模式概况和设计模式的六大原则.设计模式的六大原则是设计模式 ...

  8. Java多线程-实例解析

    Java多线程实例 3种实现方法Java中的多线程有三种实现方式:1.继承Thread类,重写run方法.Thread本质上也是一个实现了Runnable的实例,他代表一个线程的实例,并且启动线程的唯 ...

  9. Java经典设计模式之十一种行为型模式(附实例和详解)

    Java经典设计模式共有21中,分为三大类:创建型模式(5种).结构型模式(7种)和行为型模式(11种). 本文主要讲行为型模式,创建型模式和结构型模式可以看博主的另外两篇文章:Java经典设计模式之 ...

随机推荐

  1. Android中AsyncTask的使用 (包含文件的下载与存储)

    今天看到大神写的相关详解Android中AsyncTask的使用,真的很是佩服,下面我将学习到的AsynTask知识运用到项目中,其中也涉及一些文件的下载与存储到本地 啥都不说了,直接上代码,我将对其 ...

  2. mybatis 一次执行多条SQL MySql+Mybatis+Druid之SqlException:sql injection violation, multi-statement not allow

    如果用JDBC jdbc.jdbcUrl=jdbc:mysql://127.0.0.1:3306/database?useUnicode=true&characterEncoding=utf8 ...

  3. Android开发:《Gradle Recipes for Android》阅读笔记(翻译)3.3——整合resource文件

    问题: 想要在product的flavor里面改变图片,文字或者其它资源. 解决方案: 在flavor里面增加合适的资源目录,并且改变他们包含的值. 讨论: 考虑下3.2章的“hello world ...

  4. poj 3670(LIS)

    // File Name: 3670.cpp // Author: Missa_Chen // Created Time: 2013年07月08日 星期一 21时15分34秒 #include < ...

  5. 【BZOJ2730】[HNOI2012]矿场搭建 Tarjan

    [BZOJ2730][HNOI2012]矿场搭建 Description 煤矿工地可以看成是由隧道连接挖煤点组成的无向图.为安全起见,希望在工地发生事故时所有挖煤点的工人都能有一条出路逃到救援出口处. ...

  6. Delphi运算符及优先级

    单目运算符 (最高优先级) @ 取变量或函数的地址(返回一个指针) not 逻辑取反或按位取反 乘除及按位运算符 * 相乘或集合交集 / 浮点相除 div 整数相除 mod 取模 (整数相除的余数) ...

  7. 2014-08-28——移动端,触摸事件 touchstart、touchmove、touchend、touchcancel

    1.Touch事件简介在移动终端上的web页面触屏时会产生ontouchstart.ontouchmove.ontouchend.ontouchcancel 事件,分别对应了触屏开始.拖拽及完成触屏事 ...

  8. ABAP 多行消息分别显示弹窗

    *&---------------------------------------------------------------------* *& Report YT_POPUP_ ...

  9. BAPI: TRANSACTION_BEGIN的作用

    大概知道是启动一个新会话, CALL FUNCTION 'TRANSACTION_BEGIN' 业务数据处理, CALL FUNCTION 'TRANSACTION_END' 详细功能不清楚. CLE ...

  10. Python基础-re正则模块

    一.简介: 正则表达式:是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过re模块实现,正则表达式模式被编译成一系列的字节码,然后由用C编写的匹配引擎执行. 二.字 ...