多线程——用创建线程的两种方式分别解决经典窗口卖票问题
2016-08-19 20:33
525 查看
/** * 窗口卖票经典实例,第一种继承Thread类多线程进行解决 * * * 需求:四个窗口同时卖票。票数100张 * * 分析: * 一个有100张票,卖票的动作是四个窗口所使用的,并且是同时进行的,那么就要使用多线程技术。 * * 怎么创建线程? * 1.继承Thread类,并且重写run方法。 * 2.将卖票的动作定义到run方法当中。 * */ package com.work.wor01; class Ticket extends Thread{ private static int num = 100;//声明成静态变量,利用静态数据的共享性,避免卖重票 //private int num = 100;如果不声明成静态变量,那么四个窗口每个窗口都会卖100张票,导致重复卖票。 @Override public void run() { while(true){ //因为他要运行多少次是不确定的,具体要看cpu的调用 if(num>0){ //卖票的过程只能是正数,所以在这里放了一个判断 System.out.println(Thread.currentThread().getName()+"...sale"+num--); }else{ break; } } } } public class ThreadTicket { public static void main(String[] args) { Ticket t1 = new Ticket(); Ticket t2 = new Ticket(); Ticket t3 = new Ticket(); Ticket t4 = new Ticket(); t1.start(); t2.start(); t3.start(); t4.start(); } }
</pre><pre code_snippet_id="1840947" snippet_file_name="blog_20160819_4_1957035" name="code" class="java">
</pre><pre code_snippet_id="1840947" snippet_file_name="blog_20160819_5_7671655" name="code" class="java"><pre name="code" class="java">/** * 将卖票的例子通过另外一种线程创建的方式写出来。 * 创建线程方式二: * 1.定义一个类,让他去实现runnable接口。 * 2.重写runnable接口当中的run方法,然后将线程将要运行的方法存储到run方法当中来。 * 3.创建该接口的实现类的对象。 * 4.通过Thread类进行线程的创建,并且将runnable接口的实现类的对象作为Thread的构造函数的参数传递进去。 * 5.调用Thread类当中的start方法去运行线程。 * * 为什么传递? * 当线程对象创建时,就要明确运行哪个run方法(明确线程任务),那这个run方法就要明确是被哪个对象所调用的。 * 所以我们就可以将run方法所属的对象传递到Thread的构造函数。 * * runnable接口的由来其实就是线程 中的任务进行了对象的封装,将线程任务进行封装之后, * 通过runnable接口可以降低耦合性。 * * 如果继承了Thread类,就要去重写他的run方法,那么thread类的子类就封装了线程的任务, * 而且他本身还是一个线程对象,这就是任务和对象耦合性过高,不利于拓展。 * * * 第一种方式: * class Demo extends Thread{ * public void run(){ * //线程的任务 * } * } * * 创建线程: * Demo d = new Demo(); //带有具体的任务的线程的对象 * d.start(); * 这个对象是一个线程的对象,任务就是与他绑定的任务,那么它还能绑定其他任务么? * 答:不能,这个问题怎么解决,用第二种方式创建线程。 * * 第二种方式创建线程:实现Runnable接口 * class Demo implements Runnable{ * public void run(){ * //线程的任务 * } * } * 创建并运行线程 * Demo d = new Demo(); //这是一个线程任务的对象 * Thread t = new Thread(d); //布置了任务到线程对象当中。 * t.start(); * * 以后在写多线程的时候,尽量用第二种方式:实现Runnable接口。 * 避免了单继承的局限性。 * * 通过画图分析,分析错票产生的原因: * 已经判断为票数了,线程被阻塞了,先一次被切换到不需要判断了。 * 局部变量不会出现数字错乱的现象,而成员变量会出现数组出现负数的现象。 * * * */ package com.work.wor01; class Ticket1 implements Runnable{ private int num = 100; @Override public void run() { while(true){ if(num>0){ // try { // 在指定的毫秒数加指定的纳秒数内让当前正在执行的线程休眠(暂停执行)会产生负数票 // Thread.sleep(10); // } catch (InterruptedException e) { // e.printStackTrace(); // } System.out.println(Thread.currentThread().getName()+"...sale"+num--); }else{ break; } } } } public class ThreadTicket02 { public static void main(String[] args) { Ticket1 t = new Ticket1(); //Thread类的对象和Thread类的子类的对象都是线程的对象。 //但是t并不是线程的对象。 //向四个线程当中传入的是同一个t对象,是因为线程执行的是同样的任务。 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(); } }
相关文章推荐
- 多线程的安全问题。 创建线程的两种方式区别
- 多线程委托之跨线程问题分析--在创建窗口句柄之前,不能在控件上调用 Invoke 或 BeginInvoke(解决方法已更新)
- Java 中的多线程-两种创建方式,定时器的应用,线程的安全问题可以用银行转账来说明
- java多线程总结一:线程的两种创建方式及优劣比较
- java多线程总结一: 线程的两种创建方式及优劣比较
- 利用委托解决多线程中“不是此控件创建的线程”的问题
- 工作线程中调用UI线程创建的窗口的UpdateData会导致Assert的问题及解决办法.
- java多线程总结一: 线程的两种创建方式及优劣比较
- java多线程总结一:线程的两种创建方式及优劣比较
- 工作线程中调用UI线程创建的窗口的UpdateData会导致Assert的问题及解决办法
- 多线程基础:两种常见的创建线程的方式
- java多线程总结一:线程的两种创建方式及优劣比较
- 多线程-01,创建线程的两种方式
- java多线程总结一: 线程的两种创建方式及优劣比较
- 黑马程序员—多线程的两种创建方式与多线程安全问题
- 多线程 创建线程的两种方式
- 【多线程】两种方式创建线程
- Java【多线程知识总结(5)】比较继承Thread类创建线程和实现Runnable接口创建线程这两种方式
- 多线程_Thread类简介及创建线程的两种方式
- 04.多线程--06.【同步方式在线程两种创建方式中的可行性】【同步代码块和同步函数的关系】【多线程程序设计思路总结】