package com.ljl.org.test4; /** *@DEMO:Interview *@Author:jilongliang *@Date:2013-4-17 * * 分别使用Runnable接口和Thread类编程实 编写一应用程序创建两个线程一个线程打印输出1—1000之间所有的奇数(Odd Number) * 另外一个线程打印输出1-1000之间所有的偶数(Even Number)要求两个线程随机休眠一 段时间后 继续打印输出下一个数 * * 创建线程有两种方式: 1.实现Runnable接口 2.继承Thread类 * 实现方式和继承方式有啥区别? * 实现方式的好处:避免了单继承的局限性 在定义线程时. * 建议使用实现方式 * 区别: * 继承Thread:线程代码存放Thread子类run方法中 实现 * Runnable:线程代码存放接口的子类的run方法 * wait释放资源,释放锁 * sleep释放资源,不释放锁 */ @SuppressWarnings("all") public class Thread1 { public static void main(String[] args) { //方法一 /* OddNumber js = new OddNumber(); js.start(); EvenNumber os = new EvenNumber(); os.start(); while (true) { if (js.i1 == 1000 || os.i2 == 1000) { System.exit(-1); } } */ //方法二 OddNum on=new OddNum(); EvenNum en=new EvenNum(); new Thread(on).start(); new Thread(en).start(); while (true) { if (on.i1 == 1000 || en.i2 == 1000) { System.exit(-1); } } } } /** * ============================继承Thread的线程=============================== */ class EvenNumber extends Thread { int i2; @Override public void run() { for (i2 = 1; i2 <= 1000; i2++) { if (i2 % 2 == 0) { System.out.println("偶數" + i2); } try { sleep((int) (Math.random() * 500) + 500); } catch (Exception e) { } } } } class OddNumber extends Thread { int i1; @Override public void run() { for (i1 = 1; i1 <= 1000; i1++) { if (i1 % 2 != 0) { System.out.println("奇數" + i1); } try { sleep((int) (Math.random() * 500) + 500); } catch (Exception e) { } } } } /** * ============================实现Runnable的线程=============================== */ @SuppressWarnings("all") class OddNum implements Runnable { int i1; @Override public void run() { for (i1 = 1; i1 <= 1000; i1++) { if (i1 % 2 != 0) { System.out.println("奇數" + i1); } try { new Thread().sleep((int) (Math.random() * 500)+500); } catch (Exception e) { } } } } @SuppressWarnings("all") class EvenNum implements Runnable { int i2; @Override public void run() { for (i2 = 1; i2 <= 1000; i2++) { if (i2 % 2 == 0) { System.out.println("偶數" + i2); } try { /**在指定的毫秒数内让当前正在执行的线程休眠 * Math.random()一个小于1的随机数乘于500+500,随眠时间不会超过1000毫秒 */ //new Thread().sleep((int) (Math.random() * 500)+500); new Thread().sleep(1000);//也可以指定特定的参数毫秒 } catch (Exception e) { } } } } 在Java中,创建和使用线程主要有两种方式,一种是继承Thread类,另一种是实现Runnable接口。这两种方式在使用上有一些区别,每种方式都有其特定的用法和特点。 继承Thread类的方式。通过继承Thread类来创建线程,需要将线程要执行的代码放在继承Thread类的子类的run()方法中。这种方式实现线程较为直观,因为可以直接调用Thread类的方法。例如,在给定的代码示例中,EvenNumber和OddNumber类都继承自Thread类,并且重写了run()方法来打印特定的数字。创建线程时,只需要创建相应的Thread子类的实例,并调用start()方法启动线程即可。然而,继承Thread类的方式有一个缺点,即Java不支持多重继承,这意味着如果一个类已经继承了另一个类,就不能再继承Thread类,这限制了类的继承结构。 接下来是实现Runnable接口的方式。通过实现Runnable接口来创建线程,需要将线程要执行的代码放在实现了Runnable接口的类的run()方法中。这种方式的优点在于,由于Java支持类的多重实现,因此可以在不牺牲继承其他类功能的同时,通过实现Runnable接口来创建线程。在示例中,OddNum和EvenNum类都实现了Runnable接口,通过实现run()方法来打印数字。创建线程时,需要创建Thread类的实例,并将Runnable对象作为参数传递给Thread的构造函数,然后调用start()方法启动线程。这种方式更加灵活,也更推荐使用,因为它避免了单继承的局限性。 两种方式在同步机制上有所不同。当线程中调用wait()方法时,当前线程会释放对象的锁,并进入等待状态,直到其他线程调用同一个对象的notify()或notifyAll()方法才能唤醒。而sleep()方法则不会释放对象锁,它仅仅是让当前线程暂停执行指定的时间。在代码示例中,sleep()方法被用在打印奇数和偶数的线程中,用于模拟随机休眠一段时间后继续执行的情况。 在并发编程中,线程安全也是一个重要概念。如果多个线程访问共享资源,需要确保操作的原子性、可见性和有序性,以避免数据不一致和竞态条件等问题。Java提供了synchronized关键字、volatile关键字以及其他并发工具来帮助开发者确保线程安全。 示例代码中还包含了一个main方法,它是程序的入口点。在这个main方法中,程序通过两种方式创建了两个线程:一个打印1到1000之间的所有奇数,另一个打印所有偶数。通过使用while循环,程序会持续运行直到两个线程都完成了它们的任务。 总结来说,Java通过两种方式提供了创建和管理线程的机制。继承Thread类的方式简单直观,但限制了继承结构;实现Runnable接口的方式更加灵活,适合复杂的应用场景。掌握这两种方式,以及它们在并发编程中的应用,对于编写有效的多线程程序至关重要。
- 粉丝: 52
- 资源: 62
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
最新资源
- (174808034)webgis课程设计文件
- (177121232)windows电脑下载OpenHarmony鸿蒙命令行工具hdc-std
- (177269606)使用Taro开发鸿蒙原生应用.zip
- (170644008)Eclipse+MySql+JavaSwing选课成绩管理系统
- (14173842)条形码例子
- (176419244)订餐系统-小程序.zip
- Java Web实现电子购物系统
- (30485858)SSM(Spring+springmvc+mybatis)项目实例.zip
- (172760630)数据结构课程设计文档1
- 基于simulink的悬架仿真模型,有主动悬架被动悬架天棚控制半主动悬架 1基于pid控制的四自由度主被动悬架仿真模型 2基于模糊控制的二自由度仿真模型,对比pid控制对比被动控制,的比较说明