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

多线程入门(一)

时间:2020-01-12 20:11:05      阅读:77      评论:0      收藏:0      [点我收藏+]

标签:停止   UNC   fun   执行   抛出异常   tle   try catch   over   bfd   

线程与进程

进程:系统上面运行的一个程序就是一个进程。一个进程包含一到多个线程。
线程:可以看成是一组指令的集合。通常由操作系统来负责多个线程的调度喝执行
总结:进程是线程的集合体,每一个线程都是进程中的一条执行路径。

为什么使用多线程

多线程的好处是可以有效的提高程序的运行效率。可以比作是有多个人合作完成原来一个人的工作。 多个线程互相不干扰,一个任务的崩溃不会影响到另外一个任务。

多线程应用场景

如:迅雷下载、后台任务、分布式计算。

多线程创建方式(常用)

1. 继承Thread类,重写run方法。

public class MyThread extends Thread {
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("run:i="+i);
        }
    }
}

创建线程完成之后可以通过start()方法来启动线程:

public class Test {
    public static void main(String[] args) {
        System.out.println("开始创建线程.........");
        MyThread thread = new MyThread();
        // 启动线程用start()方法,不能直接调用run()方法,若调用run()方法,线程不起作用
        thread.start();
        System.out.println("线程正在运行.........");

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

线程执行通过操作系统进行随机分配,多个线程交叉执行。例如该程序执行结果中:

...
main:i=51
run:i=76
main:i=52
run:i=77
run:i=78
main:i=53
run:i=79
run:i=80
main:i=54
main:i=55
main:i=56
...

2. 实现Runnable接口,重写run()方法

public class MyThread2 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {
            System.out.println("run:i="+i);
        }
    }
}

启动线程的方法与继承Thread类不同,因为实现Runnable的类中没有start()方法,所以直接调用该实例的start()是错误的,调用方法:

public class Test {
    public static void main(String[] args) {
        System.out.println("开始创建线程.........");

        MyThread2 thread2 = new MyThread2();
        new Thread(thread2).start();
        System.out.println("线程正在运行.........");

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

一般使用中实现Runnable接口优于继承Thread类,因为Java单继承,但可以实现多个接口。

3. 使用匿名内部类创建

public class Test {
    public static void main(String[] args) {
        System.out.println("开始创建线程.........");

//        匿名内部类
        new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    System.out.println("run:i="+i);
                }
            }
        }).start();

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

常用api

常用的线程api 
start() 启动线程
currentThread() 获取当前线程对象
getID() 获取当前线程ID ID随机分配
getName() 获取当前线程名称 Thread-编号 该编号从0开始
sleep(long second) 休眠线程,参数为时间(毫秒)
stop() 停止线程
setDaemon(boolean flag) 设置线程为守护线程
   
常用线程构造函数 
Thread() 分配一个新的Thread对象
Thread(String name) 分配一个具有指定名称的的Thread对象
Thread(Runnable r) 分配一个Thread对象(通过实现Runnable接口创建的)
Thread(Runnable r,String name) 分配一个指定名称的Thrad对象(通过实现Runnable接口创建的)
   

在run()方法当中不能抛出异常,只能通过try catch来捕获异常

线程的生命周期

技术图片

  • 新建状态(New):使用New创建一个线程的时候,但没有调用start()方法启动的时候,该线程处于新建状态。
  • 就绪状态(Runnable):线程调用start()方法之后,等待分配调度的时候。
  • 运行状态(Running):就绪状态的线程获得CPU,开始执行run()方法的代码时。
  • 阻塞状态(Blocked):处于运行状态的线程失去所占用资源的时候进入阻塞状态。
  • 死亡状态(Dead):线程中的run()方法代码执行完毕。

线程进入阻塞状态的原因:

  1. 线程调用sleep()进入睡眠状态。
  2. 线程调用一个I/O上被阻塞的操作,即该线程在输入输出完成之前不会返回他的调用者。
  3. 线程试图得到一个锁,而该锁正被其他线程持有。
  4. 线程在等待某个触发条件。

守护线程和非守护线程

守护线程:当进程不存在或者主线程停止,守护线程也随之停止。 非守护线程:一般指用户线程,与主线程互不影响。

同步和异步的区别

同步:代码自上而下执行,上面的任务执行完成之后才可以执行下面的方法。 异步:多个任务并行执行,任务之间互不影响。

join()方法的使用

A线程中调用B线程的join()方法,表示A线程等待B线程死亡之后才开始执行。

public class TestJoin {
    public static void main(String[] args) {
        Thread thread = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100; i++) {
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("子线程"+i);
                }
            }
        });
        thread.start();
        System.out.println("====================");
        try {
            // 主线程调用join方法表示主线程释放自己的资源交给子线程,等子线程死亡之后再执行
            thread.join();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        for (int i = 0; i < 100; i++) {
            System.out.println("主线程"+i);
        }
    }
}

多线程入门(一)

标签:停止   UNC   fun   执行   抛出异常   tle   try catch   over   bfd   

原文地址:https://www.cnblogs.com/kfw5264/p/12183404.html

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