Java多线程

来源:互联网 发布:vmware中linux上网 编辑:程序博客网 时间:2024/06/07 10:36

多线程的实现

1、使用Thread类实现多线程

java.lang.Thread是一个负责线程操作的类,任何类只需要继承了Thread类就可以成为一个线程的主类,但是既然是主类一定要有他的方法,而线程启动的主方法需要覆写Thread类中的run()方法才可以。
范例:

package cn.mldn.demo;class MyThread extends Thread{      //线程的主体类    private String title;    public MyThread(String title){        this.title = title;    }    @Override    public void run() {             //线程的主方法        // TODO Auto-generated method stub        for (int i = 0; i < 50; i++) {            System.out.println(this.title+"运行,i="+i);        }    }}public class TestDemo{    public static void main(String args[]){        MyThread mt1 = new MyThread("线程A");        MyThread mt2 = new MyThread("线程B");        MyThread mt3 = new MyThread("线程B");        mt1.start();        mt2.start();        mt3.start();    }}

多线程是多个线程彼此交替进行,通过以上的代码可以得出结论:要想启动线程必须依靠Thread类的start()方法执行,线程启动后会默认调用run()方法。

2、实现Runnable接口实现多线程

使用Thread类的确是可以方便的进行多线程的实现,但是这种方式的最大缺点就是单继承,

public interface Runnable{    public void run();}

注:如何区分新老接口:
在JDK之中,由于其发展时间较长,那么出现一些新的接口和老的接口,这两者有一个最早提供的接口方法里面不加public,所有新的接口都有public。

package cn.mldn.demo;class MyThread implements Runnable{     //线程的主体类    private String title;    public MyThread(String title){        this.title = title;    }    @Override    public void run() {             //线程的主方法        // TODO Auto-generated method stub        for (int i = 0; i < 50; i++) {            System.out.println(this.title+"运行,i="+i);        }    }}public class TestDemo{    public static void main(String args[]){        MyThread mt1 = new MyThread("线程A");        MyThread mt2 = new MyThread("线程B");        MyThread mt3 = new MyThread("线程c");        /*        mt1.start(); //这样的写法会报错,因为start属于Thread类的方法,不能直接调用        mt2.start();        mt3.start();        */        new Thread(mt1).start();//这样是正确的        new Thread(mt2).start();        new Thread(mt3).start();    }}

这样写唯一的好处是避免单继承的局限,要想启动多线程要依靠Thread类的 start()方法完成,所以这个时候需要将原来的代码mt1.start();改为new Thread(mt1).start();

面试题:Thread类和Runnable接口实现多线程的区别?
Thread类的定义:

public class Thread extends Object implements Runnable

可以看出Thread类也是Runnable接口的子类

这里写图片描述

以上图示非常像代理设计模式,但是他并不是严格意义上的代理设计模式,因为所谓的代理设计模式,代理主题能够使用的方法依然是接口中定义的run()方法,而此处的代理主题调用的是start()方法,所以只能说形式上类似于代理设计模式,但本质上还是有差别的。

使用Runnable接口可以更方便的表示出数据共享。

数据共享的实例(卖票系统):

package cn.mldn.demo;class MyThread implements Runnable{     //线程的主体类    private int ticke = 5 ; //一共5张票    @Override    public void run() {             //线程的主方法        // TODO Auto-generated method stub        for (int i = 0; i < 5; i++) {            if(ticke>0){                System.out.println("卖票,ticke="+ticke--);            }                   }           }}public class TestDemo{    public static void main(String args[]){        MyThread mt = new MyThread();        new Thread(mt).start();        new Thread(mt).start();        new Thread(mt).start();    }} 

面试题:
请解释多线程的两种实现方式以及区别?并分贝编写程序以验证两种实现方式。

  • 多线程的两种实现方式都需要一个线程的主类,而这个类可以实现Runnable接口或继承Thread类,不管使用何种方式都必须在子类中覆写run()方法,此方法为线程的主方法。
  • Thread类是Runnable接口的子类,而且使用Runnable接口可以避免单继承局限,以及更加方便的实现数据共享的概念。
    程序实现:
    这里写图片描述

面试题:请问多线程造作同一资源的时候要来考虑哪些,会带来哪些问题?
多线程访问同一资源的时候一定要考虑到同步问题,但是过多的同步会带来死锁。

面试题:请解释sleep()和wait()的区别?
sleep()是Thread类定义的static方法,表示线程休眠,休眠到一定时间后自动唤醒。
wait()是Object类定义的方法,表示线程等待,一直执行到notify()或notifyAll()之后才结束等待。

原创粉丝点击