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

(十八)多线程

时间:2016-10-19 19:12:31      阅读:225      评论:0      收藏:0      [点我收藏+]

标签:

多线程

多线程与多进程的区别在于每个进程拥有自己的一整套变量,线程则共享数据。与进程相比,线程更加“轻量级”,创建和撤销一个线程比启动新进程开销要小得多。

 

实现多线程有两种方法:

  1. 实现Runnable接口
  2. 继承Thread类

以下采用两种方法分别实现多线程

实现Runnable接口

public class Football implements Runnable{
    private String player;
    private static int steps=10;
    public Football(String name){
        player = name;
    }
    @Override
    public void run() {
        while(true){
            System.out.println(Thread.currentThread().getId()+":"+player+" is playing football");
            try {
                Thread.currentThread();
                Thread.sleep(1200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

public class Basketball implements Runnable {
    private String player;
    private static int steps=20;
    public Basketball(String name){
        player = name;
    }
    @Override
    public void run() {
        while(true){
            System.out.println(Thread.currentThread().getId()+":"+player+" is playing basketball");
            try {
                Thread.currentThread();
                Thread.sleep(700);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        
    }
}


public class Play {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Runnable foot = new Football("Tom");
        Runnable basket = new Basketball("John");
        
        Thread t1 = new Thread(foot);
        Thread t2 = new Thread(basket);
        
        t1.start();
        t2.start();
    }

}

输出:
8:Tom is playing football
9:John is playing basketball
9:John is playing basketball
8:Tom is playing football
9:John is playing basketball
9:John is playing basketball
8:Tom is playing football
9:John is playing basketball
9:John is playing basketball
8:Tom is playing football
9:John is playing basketball

继承Thread类

public class Football extends Thread{
    private String player;
    public Football(String name){
        player = name;
    }
    public void run(){
        while(true){
            System.out.println(Thread.currentThread().getId()+":"+player+" is playing football");
            try {
                Thread.currentThread();
                Thread.sleep(1200);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}




public class Basketball extends Thread{
    private String player;
    public Basketball(String name){
        player = name;
    }
    public void run(){
        while(true){
            System.out.println(Thread.currentThread().getId()+":"+player+" is playing basketball");
            try {
                Thread.currentThread();
                Thread.sleep(700);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}



public class Play {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Thread t1 = new Football("Tom");
        Thread t2 = new Basketball("John");
        
        t1.start();
        t2.start();
    }

}


输出:
8:Tom is playing football
9:John is playing basketball
9:John is playing basketball
8:Tom is playing football
9:John is playing basketball
9:John is playing basketball
8:Tom is playing football
9:John is playing basketball
9:John is playing basketball
8:Tom is playing football
9:John is playing basketball
8:Tom is playing football

中断线程

当线程的run方法执行到结尾,或者出现未捕获的异常便会停止线程。

可以通过Thread.currentThread().interrupt()来强制终止当前线程。当对一个线程调用该方法时,线程的中断状态会被置位。我们便可以通过Thread.currentThread().isInterrupted()检查这个标志判断线程是否被中断。

但是,如果线程被阻塞(调用sleep或wait),就无法检测中断状态。当一个被阻塞的方法调用interrupt方法时,会被InterruptedException异常中断。

当中断状态被被置位时,调用sleep方法,他不会休眠,而是清除这一状态并抛出InterruptedException异常。

//更改Football部分代码
public class Football implements Runnable{
    private String player;
    private static int steps=10;
    public Football(String name){
        player = name;
    }
    @Override
    public void run() {
        while(!Thread.currentThread().isInterrupted()){
            steps--;
            System.out.println(Thread.currentThread().getId()+":"+player+" is playing football");
            try {
                Thread.currentThread();
                Thread.sleep(800);
            } catch (InterruptedException e) {e.printStackTrace();}
            
            if(steps<=0){
                Thread.currentThread().interrupt();//设置中断标志
                try {
                    Thread.sleep(800);//前面设置了中断标志,因此此处调用会发生InterruptedException异常
                } catch (InterruptedException e) { //发生InterruptedException异常后,中断标志会被清除
                    System.out.println("vvvvvvvvvvvvvvvvvvvvvvvv");
                    System.out.println("线程:"+Thread.currentThread().getId()+" 调用sleep方法发生异常!");
                    try {
                        Thread.sleep(800); //因为中断标志被清除了,因此这里调用没问题
                        System.out.println("线程:"+Thread.currentThread().getId()+" 调用sleep方法成功!");
                    } catch (InterruptedException e1) {}
                    System.out.println("^^^^^^^^^^^^^^^^^^^^^^^^");
                }
            }
        }
        System.out.println("Footbal线程被终止!");
    }
}

输出

9:John is playing basketball
9:John is playing basketball
8:Tom is playing football
9:John is playing basketball
8:Tom is playing football
9:John is playing basketball
vvvvvvvvvvvvvvvvvvvvvvvv
线程:8 调用sleep方法发生异常!
9:John is playing basketball
线程:8 调用sleep方法成功!
^^^^^^^^^^^^^^^^^^^^^^^^
8:Tom is playing football
9:John is playing basketball

线程状态

线程有6种状态

    1. 新创建
    2. 可运行
    3. 被阻塞
    4. 等待
    5. 计时等待
    6. 被终止

五个阶段:创建、就绪、运行、阻塞、终止

新建线程

new Thread(r)新建一个线程,但还没有运行。

可运行线程

调用start()方法,线程处于runnable状态。可能在运行也可能没有运行。取决于系统。

阻塞线程

当一个线程试图获取一个内部的对象锁,而该锁被其他线程所持有,则该线程处于阻塞状态。当其他线程释放该锁,并且线程调度器允许本线程持有它的时候,该线程变成非阻塞状态。

等待线程

当线程等待另一个线程通知调度器一个条件时,它自己进入等待状态。在调用Object.wait方法或Thread.join方法,,或是等待java.util.concurrent库中的Lock或Condition时,就会出现这种情况。

计时等待

有几个方法有一个超时参数,调用它们会导致线程进入计时等待。比如Thread.sleep(),Object.wait,Thread.join,Lock.tryLock,Condition.await。

终止线程

以下两种可能:

因为run方法正常退出而死亡。

因为一个未被捕获的异常而终止了run方法而意外死亡。

可以调用Thread.currentThread().join()或Thread.currentThread().join(long millis)来等待进程的终止。

线程状态图

 

 

技术分享

 

线程状态转换

技术分享

线程属性

 

 

(十八)多线程

标签:

原文地址:http://www.cnblogs.com/wuchaodzxx/p/5978183.html

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