Java线程

Java线程

线程基础

什么是线程

线程,是进程的一部分,一个没有线程的进程可以被看作是单线程的。线程有时又被称为轻权进程或轻量级进程,也是 CPU 调度的一个基本单位。是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。

为什么使用线程

(1)易于调度。
(2)提高并发性。通过线程可方便有效地实现并发性。进程可创建多个线程来执行同一程序的不同部分。
(3)开销少。创建线程比创建进程要快,所需开销很少。
(4)利于充分发挥多处理器的功能。通过创建多线程进程,每个线程在一个处理器上运行,从而实现应用程序的并发性,使每个处理器都得到充分运行。
(5)线程能够使UI响应更快、利用多处理器系统、简化建模、执行异步或后台处理

线程与进程

联系
(1)一个线程只能属于一个进程,而一个进程可以有多个线程,但至少有一个线程。
(2)资源分配给进程,同一进程的所有线程共享该进程的所有资源。
(3)处理机分给线程,即真正在处理机上运行的是线程。
(4)线程在执行过程中,需要协作同步。不同进程的线程间要利用消息通信的办法实现同步。线程是指进程内的一个执行单元,也是进程内的可调度实体
区别
(1)调度:线程作为调度和分配的基本单位,进程作为拥有资源的基本单位
(2)并发性:不仅进程之间可以并发执行,同一个进程的多个线程之间也可并发执行
(3)拥有资源:进程是拥有资源的一个独立单位,线程不拥有系统资源,但可以访问隶属于进程的资源.
(4)系统开销:在创建或撤消进程时,由于系统都要为之分配和回收资源,导致系统的开销明显大于创建或撤消线程时的开销。

如何实现线程

继承Thread类
//Thread的源码也是通过继承Runnable接口实现
public class Thread implements Runnable
/**
 * 继承Thread类实现线程
 * @author CronGermOil
 */
public class JavaThread extends Thread {

    public JavaThread() {
        //使用super直接调用Thread里的构造方法
//        public Thread(String name) {
//            init(null, null, name, 0);
//        }
        super("Reus");
    }
    /**
     * 覆写Thread里的run方法
     */
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            try{
                //线程休眠,以毫秒为单位
                Thread.sleep(1000);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            System.out.println(this.getName()+i);
        }
    }
}
继承Runnable接口
/**
 * 实现Runnable接口创建线程
 * @author CornGermOil
 */
public class JavaRunnable implements Runnable {
    @Override
    public void run() {
        for(int i=0;i<10;i++){
            try{
                Thread.sleep(1000);
            }catch(InterruptedException e){
                e.printStackTrace();
            }
            System.out.println("实现runnable方式运行"+i);
        }
    }
}
继承Callable接口创建线程
/**
 * 实现Callable来创建线程
 * @author CornGermOil
 */
public class JavaCallable implements Callable<String> {
    @Override
    public String call() throws Exception {
        for (int i=0;i<10;i++) {
            System.out.println("*****线程执行:"+i);
        }
        return "实现Callable来创建线程";
    }
}
三种方法的区别
1.创建方式的区别:
Thread是类,仅允许单继承,Runnable和Callable属于接口,允许多继承
2.内容的区别
Thread源码也是实现的Runnable,两种方法都需要重写run()方法,run()方法没有返回值,Callable接口提供了call()方法,可以通过Future接口获取返回值。
3.实现方式的区别:
Thread的实现方式
        //实例化线程
        JavaThread javaThread = new JavaThread();
        //启动线程
        javaThread.start();
Runnable的实现方式
       //实例化线程
       JavaRunnable javaRunnable = new JavaRunnable();
       //启动线程
       new Thread(javaRunnable).start();
Callable的实现方式
       //将Callable实例包装在FutureTask类中,从而实现与Runnable接口关联
        FutureTask<String> task = new FutureTask<>(new JavaCallable());
        //启动线程
        new Thread(task).start();
        //获取返回结果
        System.out.println("线程执行结果:"+task.get());
4.在三种方式实现的线程同时启动时,Callable创建的线程总是先完成运行,然后Thread和Runnable创建的线程交替完成(截取部分运行结果)?
*****线程执行:0
*****线程执行:1
*****线程执行:2
*****线程执行:3
线程执行结果:实现Callable来创建线程
实现runnable方式运行0
Reus0
Reus1
实现runnable方式运行1
实现runnable方式运行2
Reus2
Reus3
实现runnable方式运行3

线程的生命周期

img

线程创建
在Java程序中,每个Java程序都至少包含一个线程:主线程,除了主线程其它的线程或是通过Thread构造器或实例化Thread的类创建。
创建线程可以通过继承Thread类、实现Runnable接口或实现Callable接口来实现
线程就绪
线程创建以后并不会运行,也就是说在未调用start()方法前线程是没有启动的,新建的Thread对象在线程启动前或结束后都是存在的,通常来说,在构造器中调用start()方法启动线程不是个good idea,应该提供一个启动线程的start()方法或者init()方法。线程在经过start()方法调用后会进入就绪状态等待CPU调用
线程运行
当就绪状态下的线程被cpu调用后会执行run()方法,此时的线程属于运行状态
线程阻塞
等待阻塞
当运行线程时执行了wait()方法,JVM将会把该线程放入等待队列。等待被唤醒。
同步阻塞
运行(running)的线程在获取对象的同步锁时,若该同步锁被别的线程占用,则 JVM 会把该线程放入锁池(lock pool)中
其它阻塞
运行(running)的线程执行 Thread.sleep(long ms)或 t.join()方法,或者发出了 I/O 请求时,JVM 会把该线程置为阻塞状态。当 sleep()状态超时、join()等待线程终止或者超时、或者 I/O处理完毕时,线程重新转入可运行(runnable)状态。
线程死亡
1.线程到达其run()方法的末尾
2.线程抛出一个未捕获到的Exception或Error
3.调用stop()方法——不建议使用,容易导致线程死锁

规避线程风险

当多个线程访问同一数据项(如静态字段、可全局访问对象的实例字段或共享集合)时,需要确保它们协调了对数据的访问,这样它们都可以看到数据的一致视图,而且相互不会干扰另一方的更改。为了实现这个目的,Java 语言提供了两个关键字:synchronized 和 volatile。
当从多个线程中访问变量时,必须确保对该访问正确地进行了同步。对于简单变量,将变量声明成volatile 也许就足够了,但在大多数情况下,需要使用同步。
如果您将要使用同步来保护对共享变量的访问,那么必须确保在程序中所有访问该变量的地方都使用同步。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值