多线程一:两种方式实现多线程

来源:互联网 发布:spss statistics mac 编辑:程序博客网 时间:2024/05/18 01:21

多线程一:两种方式实现多线程

一.解析多线程:

A.通俗语言(和程序中的线程有一些出入):

一个公司的经理手上有一个项目【一个java项目】,安排他的员工Java中的方法】同时完成这个项目。

此时,这个经理也是干活的,不是闲着的,也就是,他是【主线程】,他的员工是【子线程】。

此时,这项工程就不是经理一个人在做了,也就是不是顺序执行了,也就是多线程操作。

B.java解析:

同一类线程共享代码和数据空间,每个线程有独立的运行栈和程序计数器(PC),线程切换开销小。(线程是cpu调度的最小单位)

在介绍线程时,有一个非常重要的概念,是“进程”。

进程:每个进程都有独立的代码和数据空间(进程上下文),进程间的切换会有较大的开销,一个进程包含1--n个线程。(进程是资源分配的最小单位)

      ☆通俗语言和java解析的不同之处:表现在这个“同时”,现实中真的能做到同时做一个工程,但是程序中,由于系统的限制,它的“同时”是CPU频繁的”切换得结果”,由于切换得频率过快,给人一种错觉上的“同时”。

     整个项目图:

 

二.多线程实现案例:

   1.顺序执行案例(单线程,它是按着程序的先后顺序走的)

    package thread;

 

class OrderThread {

       public void run() {

              while (true) {

                     System.out.println("线程学习");

              }

 

       }

 

       public void start() {

              run();

       }

 

}

 

public class Thread0 {

       public static voidmain(String[] args) {

              newOrderThread().start();

              ;

       }

}

 2.通过继承Thread实现多线程:

1.源代码:

package thread;

 

/**

 * 通过继承Thread实现多线程技术

 *

 */

/*

 * 通过继承实现Thread需要以下注意项: 第一步:继承Thread 第二步:重写run()方法 第三步:实例化本类 第四步:调用start方法,启动线程

 */

class MyThread extends Thread { // 线程一(子线程) 1.继承Thread

       @Override

       public void run() { // 2.重写run()方法

              for (int i = 0; i< 10; i++) {

                     // 设置当前线程名

                     System.out.println(Thread.currentThread().getName());// 输出当前线程名

              }

 

       }

 

}

 

public class Thread1 {

       public static voidmain(String[] args) { // 线程0(主线程)

              for (int i = 0; i< 10; i++) {

                     System.out.println(Thread.currentThread().getName());

              }

              // 3.实例化本类

              MyThread t1 = newMyThread();

              MyThread t2 = newMyThread();

              // 设置当前线程名(它也有自己默认的线程名)

              t1.setName("线程1");

              t2.setName("线程2");

              // 4.调用start方法

              t1.start();

              t2.start();

       }

}

2.运行结果:

 

3.通过实现Runable接口实现多线程

1.源代码:

 package thread;

 

/**

 * 通过实现Runnable接口实现多线程技术

 */

/*

* 通过实现Runnable需要以下注意项: 第一步:实现Runnable接口 第二步:实现run()方法 第三步:实例化本类

*     第四步:实例化当前类   第五步:实例化Thread   第六步:将当前类以参数形式传入Trhead,调用start方法,启动线程

*/

class MyThread2implements Runnable{   //1:实现Runnable接口

@Override

public void run() {     //2.实现run()方法

        for (int i = 0; i < 200; i++) {

               // 设置当前线程名

               System.out.println(Thread.currentThread().getName());// 输出当前线程名

        }

}

}

 

public classThread2 {

public static void main(String[] args) {

        for (int i = 0; i < 20; i++) {

               System.out.println(Thread.currentThread().getName());

        }

        MyThread2 t1=new MyThread2();   //3.实例化本类

         new Thread(t1,"线程一").start();  //4:实例化当前类   5:实例化Thread   6:将当前类以参数形式传入Trhead,调用start方法,启动线程

         new Thread(t1,"线程二").start();;

}

}

2.运行结果:


3.解析:

1.多线程的运行结果是不固定的,因为它的调用顺序是随机的。

   2.本实例中一共有三个线程,分别为主线程,线程一,线程二。一个程序中可以没有子线程,但是主线程是必须的。

三.两种线程实现的比较

从main函数入手,分别参考下面截图:

1.继承Thread

 

2.实现Runnable

第一种是把当前类实例化了两次,启动了两个线程。

第二种是把当前类实例化了一次,启动了两个线程。

所以,第一种是对象资源独立性的,第二种是对象资源”共享性”的。

于是:如果一个类继承Thread,则不适合资源共享。但是如果实现了Runable接口的话,则很容易的实现资源共享。

于是,实现Runnable接口比继承Thread类所具有的优势:

1):适合多个相同的程序代码的线程去处理同一个资源

2):可以避免java中的单继承的限制

3):增加程序的健壮性,代码可以被多个线程共享,代码和数据独立

4):线程池只能放入实现Runable或callable类线程,不能直接放入继承Thread的类

四.特别注意:

1.main方法其实也是一个线程。在java中所以的线程都是同时启动的,至于什么时候,哪个先执行,完全看谁先得到CPU的资源。

2.java中,每次程序运行至少启动2个线程。一个是main线程,一个是垃圾收集线程。因为每当使用java命令执行一个类的时候,实际上都会启动一个JVM,每一个jVM实习在就是在操作系统中启动了一个进程。

参考资料:http://blog.csdn.net/evankaka/article/details/44153709#t0

 哭哭本内容由安康学院"雨季"原创!

阅读全文
0 0