Java中的多线程实现方式

来源:互联网 发布:网络大电影如何赚钱 编辑:程序博客网 时间:2024/05/20 17:23

Java中的多线程实现方式

在我们的开发的过程中,常常会碰到多线程的问题,对于多线程的实现方式主要有两种:实现Runnable接口集成Thread类。对于这两种多线程实现的方式也是有一些差异的。网上针对此问题基本都是使用买票系统的例子,接下来我们就用代码来模拟下售票系统,实现2个售票点发售10张车票,一个售票点表示一个线程。

方案一

首先从最简单的做法开始,开两个Thread类进行售票。
测试代码如下

public class ticketThread extends Thread {    private int ticket = 10;    public void run() {        for(int i = 0; i < 10; i++){            if(ticket > 0){                try {                    sleep(1000);                    System.out.println(Thread.currentThread().getName()                             + "卖票 ——>" + (ticket--) );                                  } catch (Exception e) {                    // TODO: handle exception                    e.printStackTrace();                }            }        }    }    public static void main(String[] args) {        // TODO Auto-generated method stub        new ticketThread().start();        new ticketThread().start();    }}

测试结果:
Thread-0卖票 ——>10
Thread-1卖票 ——>10
Thread-1卖票 ——>9
Thread-0卖票 ——>9
Thread-1卖票 ——>8
Thread-0卖票 ——>8
Thread-1卖票 ——>7
Thread-0卖票 ——>7
Thread-0卖票 ——>6
Thread-1卖票 ——>6
Thread-0卖票 ——>5
Thread-1卖票 ——>5
Thread-1卖票 ——>4
Thread-0卖票 ——>4
Thread-1卖票 ——>3
Thread-0卖票 ——>3
Thread-1卖票 ——>2
Thread-0卖票 ——>2
Thread-0卖票 ——>1
Thread-1卖票 ——>1
结论:
从上面的测试结果可以看出,两个线程各自卖了各自的10张票而不是去卖共同的10张票,这和我们的目标多个线程去处理同一个资源相差很多。我们创建了2个ticketThread对象就等于创建了2个资源,每个资源有10张票,每个资源都在独自处理各自的资源。所以通过这个例子我们知道,在这个售票系统中,我们只能创建一个资源对象,但需要创建多个线程去处理同一个资源对象,并且每个线程上所运行的是相同的程序代码。

方案二

既然只能创建一个资源对象,那么我就只创建一个ticketThread,在额外创建两个新的线程去实现售票。

测试代码:

public class ticketThread extends Thread {    private int ticket = 10;    public void run() {        for(int i = 0; i < 10; i++){            synchronized(this){                if(ticket > 0){                    try {                        sleep(1000);                        System.out.println(Thread.currentThread().getName()                                 + "卖票 ——>" + (this.ticket--) );                                     } catch (Exception e) {                        // TODO: handle exception                        e.printStackTrace();                    }                }            }        }    }    public static void main(String[] args) {        // TODO Auto-generated method stub        ticketThread t1 = new ticketThread();        new Thread(t1, "线程1").start();        new Thread(t1, "线程2").start();    }}

测试结果:
线程1卖票 ——>10
线程1卖票 ——>9
线程2卖票 ——>8
线程2卖票 ——>7
线程2卖票 ——>6
线程1卖票 ——>5
线程1卖票 ——>4
线程2卖票 ——>3
线程2卖票 ——>2
线程2卖票 ——>1

结论:
这种情况下,我们实现了多个线程对同一个资源进行处理。这里我们创建新线程使用了
Thread(ThreadGroup groupOb, String threadName)
ticketThread作为参数传入新创建的线程。在这种情况下新创建的两个线程就去执行了ticketThread中的run()方法,这样一来就实现了两个线程对同一个资源进行处理。但就原理上来说,此方案与方案三是一样的。

方案三

使用Runnable来实现多线程。
测试代码:

public class ticketThread implements Runnable {    private int ticket = 10;    public void run() {        for(int i = 0; i < 10; i++){//          synchronized(this){                if(ticket > 0){                    try {                        Thread.sleep(1000);                        System.out.println(Thread.currentThread().getName()                                 + "卖票 ——>" + (ticket--) );                       } catch (Exception e) {                        // TODO: handle exception                        e.printStackTrace();                    }                }            }//      }    }    public static void main(String[] args) {        // TODO Auto-generated method stub        ticketThread t1 = new ticketThread();        new Thread(t1, "线程1").start();        new Thread(t1, "线程2").start();    }}

测试结果:
线程1卖票 ——>10
线程2卖票 ——>9
线程2卖票 ——>7
线程1卖票 ——>8
线程1卖票 ——>6
线程2卖票 ——>5
线程1卖票 ——>4
线程2卖票 ——>3
线程2卖票 ——>2
线程1卖票 ——>1

结论
在上面的测试代码中,我们创建了2个线程,每个县城调用的是同一个ticketThread对象中的run()方法,访问的是同一个对象的变量(ticket)的实例,这个程序就完美的满足了我们的需求。

Runnable与Thread的区别与联系

  1. 一个类只能继承一个父类,这是使用Thread的局限性,而Runnable是一个接口,只要实现这个接口就行了。所以在实际的开发过程中,是通过Runnable接口来实现的,并且Runnable更适合资源共享的实现。
  2. 使用Runnable可以比喵由于Java的单继承特性带来的局限性,我们经常碰到这样一种情况,即当我们要已经继承了某一个累的子类放入多线程中,由于一个类不能同时偶两个父类,所以不能用继承Thread类的方式,那么这个类就是只能采用Runnable接口的方式了。
  3. 实际上Thread类也是Runnbale接口的子类。
    public class Thread extends Object implements Runnable
  4. 使用Runnable对象时,Runnable定义的子类没有start()方法,只有Thread类中才有,观察Thread类,有一个构造方法public Thread(Runnable target),此构造方法接受Runanble的子类实例,也就是说可以通过Thread类来启动Runnable实现多线程。
0 0
原创粉丝点击