码迷,mamicode.com
首页 > 编程语言 > 详细

多线程(1)

时间:2015-09-01 13:59:58      阅读:150      评论:0      收藏:0      [点我收藏+]

标签:

---恢复内容开始---

什么事多线程:

我们使用多线程 程序目的就是为了提高效率.

多线程程序相当于拥有多条通路去执行。

什么事进程:

可以简单理解成就是一个应用程序.

多个线程组成了一个进程.

进程与进程之间不可能进行通信,但是同一个进程中的线程可以进行通信.

线程的两种方式:

1.1 第一种是继承 Thread类,重写run方法
  创建线程 创建我们自定义类的对象
  启动线程 调用从Thread类中继承的start方法

/*
    多线程是java中的一项技术

    java中的多线程不是面向对象的。
    
    java中怎样实现多线程(面试题)

    首行知道:java.lang包下的所有类在使用时不需要导包.

    1.java.lang.Thread  这个类就是java中的线程类.
    
        阅读帮助文档
        1.发现java中的线程有10个优先级,默认优行级为5.最高为10,最低为1
        2.java中创建线程有两种方式
            
            2.1    第一种是继承 Thread类,重写run方法
                创建线程  创建我们自定义类的对象
                启动线程  调用从Thread类中继承的start方法
*/
/*

多线程程序的无规则性

    根据这个程序的结果,发现main或run内容谁先执行,谁先执行多少个
    这个是规律的,这个叫多线程程序的无序性.

    为什么出现这种情况,是因为cpu在执行时,我们控制不了cpu的时间片
    分配,分配给哪一个线程,哪个线程就执行。

*/
/*
    当我们执行这段代码时,一共有两个线程 一个是main线程,
    另外一个是我们自定义的MyThread线程,我们管它叫子线程.
*/

class Demo2 
{
    public static void main(String[] args) 
    {
        MyThread mt=new MyThread();//创建线程对象

        mt.start();    //启动线程
        
        //mt.run(); //调用run方法

        for(int i=0;i<100;i++){
            
            System.out.println("main"+i);
        }

    }
}

/*
    自定义一个线程类
    步骤
    1.继承Thread
    2.重写run方法  
        通过查看帮助文档发现 Thread类中的run方法中没有任何内容,只是告诉我们子类要重写这个方法
    3.创建线程对象,并启动线程

    run方法作用: 要执行的子线程的内容。 
    start作用:   启动线程  jvm重新开辟运行通信
*/
/*
    调用run方法与start方法区别

    start:使该线程开始执行;Java 虚拟机调用该线程的 run 方法。

    run:使用run方法执行,main方法中调用的run。

*/
class MyThread extends Thread
{
    //重写run方法
    public void run(){
    
        for(int i=0;i<100;i++){
            
            System.out.println("run"+i);
        }
        //System.out.println("得写了从Thread类中继承的run");
    }
}

 

1.2 实现Runnable接口
Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。

 

/* 创建线程的第二种方式

    2.2 实现Runnable接口
    Runnable 接口应该由那些打算通过某一线程执行其实例的类来实现。

        步骤
        1.创建类去实现Runnable接口
        2.Runnable接口中定义了一个run方法,必须重写
        3.启动线程  将实现了Runnable接口类的对象做为参数传递给Thread构造方法,
          这样在通过Thraed对象去调用start方法时,就知道应该执行哪个run。

          例如  new Thread(实现Runnable接口对象).start();

*/
class Demo3 
{
    public static void main(String[] args) 
    {
        Runnable mr=new MyRunnable();

        //mr.start(); 不行,因为Runnable接口中没有定义start方法

        //启动线程
        Thread th=new Thread(mr);
        th.start();
        //new Thread(mr).start();
        /*
            分析上面这句话
            1.new Thread(mr)  通过这句话是不是知道 Thread类中提供一个可以接收Runnable类型的构造方法
            2.通过帮助文档发现  参数的作用就是执行这个对象所对应的run方法
        */
        

    }
}



class MyRunnable implements Runnable
{
    //重写接口中的方法
    //使用实现接口 Runnable 的对象创建一个线程时,
    //启动该线程将导致在独立执行的线程中调用对象的 run 方法。
    public void run(){
        
        System.out.println("子线程执行的内容");
    }
}
/*
    启动线程  start方法

    start方法是哪个类的    是Thread类中的。
*/

/*
    线程创建详细分析:

    创建线程 就是Thread类对象.

    实现这个Runnable接口,其实就是在定子线程中执行的内容。
    要具体的想要创建线程,必须创建Thread为对象,那Runnable
    接口中的run方法要想执行,要将其做为参数传递给Thread类.
*/
/*
//第一种方式实现

MyThread mt=new MyThread();

mt.start(); 
如果我们没有在自定义类中重写run方法,那么父类中run方法没执行任何内容
这不是我们想要的,我们只有在自定义类中重写run,完成我们想要的功能
*/


/*
//第二种实现

MyRunnable mr=new MyRunnable();

new Thread(mr).start();

这时调用的是我们实现Runnable接口中的run方法的内容.


*/

1.3 怎样创建多个子线程
2.Thread类中常用的方法

1.String getName() 得到线程的名字
2.void setName() 设置线程的名称
3.static Thread currentThread() 得到当前正在运行的线程的对象的引用

4.了解 String toString() 线程对象的字符串表示形式 包括 线程名 优先级 线程组。

创建线程两种方式
1. extends Thread
2. implements Runnable


所有的线程都有名字

class Demo4 
{
    public static void main(String[] args) 
    {
        //怎样创建多个子线程
        /*创建三个线程,分别执行a,b,c,三个方法*/

        ThreadDemo td1=new ThreadDemo();
        ThreadDemo td2=new ThreadDemo();
        ThreadDemo td3=new ThreadDemo();

        td1.setName("a");
        td2.setName("b");
        td3.setName("c");

        //System.out.println(td1.getName());
        //System.out.println(td2.getName());
        //System.out.println(td3.getName());
        td1.start();  //a
        //td2.start();  //b
        //td3.start();  //c
    }
}


class ThreadDemo extends Thread
{
    public void run(){
    
        /*
            怎样能知道是哪个线程
        */
        //System.out.println("子线程内容");
        
        //判断线程的名称,来调用相应的方法
        //System.out.println(this.getName());

        Thread th=Thread.currentThread();
        //th代表的是当前正在执行的线程对象的引用

        String threadName=th.getName();

        if("a".equals(threadName)){
            a();
        }

        if("b".equals(threadName)){
            b();
        }

        if("c".equals(threadName)){
            c();
        }



    }

    public void a(){
        System.out.println("a method");
    }

    public void b(){
        System.out.println("b method");
    }
    public void c(){
        System.out.println("c method");
    }
}

1.4  实现 Runnable接口

 

class Demo5 
{
    public static void main(String[] args) 
    {
        /*怎样创建多个线程对象*/
        
        ThreadDemo td1=new ThreadDemo();
        //ThreadDemo td2=new ThreadDemo();
        //ThreadDemo td3=new ThreadDemo();
    
    
        Thread th1=new Thread(td1);
        Thread th2=new Thread(td1);
        Thread th3=new Thread(td1);

        /*给线程起名*/
        th1.setName("a");
        th2.setName("b");
        th3.setName("c");

        th1.start();
        th2.start();
        th3.start();

    
    }
}


class ThreadDemo implements Runnable
{
    public void run(){
        
        //System.out.println("子线程执行的内容");
        String name=Thread.currentThread().getName();

        if(name.equals("a")){
            a();
        }
        if("b".equals(name)){
            b();
        }
        if("c".equals(name)){
            c();
        }

    }

    public void a(){
        System.out.println("a method");
    }

    public void b(){
        System.out.println("b method");
    }
    public void c(){
        System.out.println("c method");
    }
}

关于创建线程的两种方式区别
建议使用哪一个

1.extends Thread
2.implements Runnable

建议使用第二种,为什么?

1.java中支持多实现,而不支持多继承。
如果使用了继承,那么我们程序的可扩展性下降,因为一个类只能有一个父类
使用实现,我们可以实现多个接口,不影响我们程序的扩展性。


2.关于数据共享

2.1如果使用继承Thread类来实现数据共享,那么这个数据要static,
它的生命周期太长.

2.2如果使用实现Runnable,这时候只需有一个实现Runnable对象将其传递给
Thread类的构造方法,就可以实现多个线程操作同一个数据。

 

class Demo6 
{
    public static void main(String[] args) throws Exception
    {
        /*
        ThreadDemo td1=new ThreadDemo();
        ThreadDemo td2=new ThreadDemo();
        ThreadDemo td3=new ThreadDemo();

        td1.start();
        td2.start();
        td3.start();
        */
        /*
            以上是三个线程对象,它们内部都有自己的成员属性id。
            如果我们想要让这三个线程操作的是同一个数据id,应该怎么办?

            如果使用继承Thread类来实现数据共享,那么这个数据要static,
            它的生命周期太长.

        */

        ThreadDemo td=new ThreadDemo();
        

        Thread th1=new Thread(td);
        Thread th2=new Thread(td);
        Thread th3=new Thread(td);
            
        //Thread.sleep(10);//使用时注意抛出异常
        th1.start();    
        Thread.sleep(10);//使用时注意抛出异常
        System.out.println(td.id);

        //Thread.sleep(10);//使用时注意抛出异常
        th2.start();
        Thread.sleep(10);//使用时注意抛出异常
        System.out.println(td.id);

        //Thread.sleep(10);//使用时注意抛出异常
        th3.start();
        Thread.sleep(10);//使用时注意抛出异常
        System.out.println(td.id);

    }
}

/*
class ThreadDemo extends Thread
{
    static int id=10;

    public void run(){
        
        id++;        
    }
}
*/


class ThreadDemo implements Runnable
{
    int id=10;

    public void run(){
        
        id++;        
    }
}

多线程程序的几种状态

 

/*
    多线程程序的几种状态

    1.创建状态
    2. start 启动 运行状态
    3.冻结
    4.销毁  1. 线程结束  run运行结束  2.调用stop()不建议使用
    5.临时堵塞状态



*/
class Demo7 
{
    public static void main(String[] args) 
    {
        ThreadDemo td=new ThreadDemo();

        Thread th1=new Thread(td);
        Thread th2=new Thread(td);
        
        th1.start(); //运行
            
        th2.start(); //运行
        //new Thread(td).start(); //运行

        //System.out.println("main  message");
    }
}

class ThreadDemo implements Runnable
{
    public void run(){
    
        /*
        System.out.println("hello"+Thread.currentThread().getName());
        
        try{
            Thread.sleep(10);  //冻结
        }catch(Exception e){
            
        }

        System.out.println("world"+Thread.currentThread().getName());
        */

        for(int i=0;i<100;i++){
            
                System.out.println(Thread.currentThread().getName());
        }
    }
}

 

撒旦法说生的

 

---恢复内容结束---

多线程(1)

标签:

原文地址:http://www.cnblogs.com/lixiangyang521/p/4775340.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!