多线程——用创建线程的两种方式分别解决经典窗口卖票问题

来源:互联网 发布:java多线程调用方法 编辑:程序博客网 时间:2024/05/17 04:52
/** * 窗口卖票经典实例,第一种继承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张票,导致重复卖票。@Overridepublic 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;@Overridepublic 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();}}



0 0
原创粉丝点击