Java多线程编程

Java给多线程编程提供了内置的支持。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。
多线程是多任务的一种特别的形式,但多线程使用了更加小的资源开销。
这里定义和线程相关的另一个术语 - 进程:一个进程包括由操作系统分配的内存空间,包含一个或多个线程。一个线程不能独立的存在,它必须是进程的一部分。一个进程一直运行,直到所有的非守护线程都结束运行后才能结束。
多线程能满足程序员编写高效率的程序来达到充分利用 CPU 的目的。

一个线程的生命周期
  • 新建状态
  • 就绪状态
  • 运行状态
  • 阻塞状态
  • 死亡状态
线程的优先级

每一个Java线程都有一个优先级,这样有助于操作系统确定线程的调度顺序
Java线程的优先级是一个整数,取值范围是1(Thread.MIN_PRIORITY)——
10(Thread.MAX_PRIORITY)
默认情况下,每一个线程都会分配一个优先级NORM_PRIORITY(5)
具有较高优先级的线程对程序更重要,并且应该在低优先级的线程之前分配处理器资源。但是,线程优先级不能保证线程执行的顺序,而且非常依赖于平台。

创建一个线程

通过implements Runnable接口来创建线程
package com.bamzhy.thread;

public class RunnableDemo implements Runnable {

    private Thread t;
    private String threadName;

    //构造函数
    RunnableDemo(String name){
        threadName=name;
        System.out.println("正在创造"+threadName);
    }

    /**
     * 用start方法来启动线程,真正实现了多线程运行,这时无需等待run方法体代码执行完毕而直接继续执行下面的代码。
     * 通过调用Thread类的start()方法来启动一个线程,这时此线程处于就绪(可运行)状态,并没有运行,一旦得到cpu时间片,就开始执行run()方法。
     * 这里方法run()称为线程体,它包含了要执行的这个线程的内容,Run方法运行结束,此线程随即终止。
     */

    @Override
    public void run() {
        System.out.println("正在运行"+threadName);
        try{
            for (int i = 0; i < 4 ; i++) {
                System.out.println("这是 " + threadName + "  " + i);
                //让线程睡眠
                Thread.sleep(50);
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
            System.out.println( threadName + " 被打断了.");
        }
        System.out.println( threadName + " 正在退出.");
    }
    //只有调用了start方法以后线程才会运行
    public void start(){
        System.out.println("正在开启"+threadName);
        if (t==null){
            t=new Thread(this,threadName);
            System.out.println(threadName+"开启成功");
            t.start();
        }
    }
}

这个是结果:

正在创造线程1
正在开启线程1
正在创造线程2
正在开启线程2
正在运行线程1
这是 线程1  0
正在运行线程2
这是 线程2  0
这是 线程1  1
这是 线程2  1
这是 线程1  2
这是 线程2  2
这是 线程1  3
这是 线程2  3
线程1 正在退出.
线程2 正在退出.
通过extends Thead类来创建线程

创建一个线程的第二种方法是创建一个新的类,该类继承 Thread 类,然后创建一个该类的实例。
继承类必须重写 run() 方法,该方法是新线程的入口点。它也必须调用 start() 方法才能执行。
该方法尽管被列为一种多线程实现方式,但是本质上也是实现了 Runnable 接口的一个实例。
代码基本相同

Run方法和Start方法的区别

start()方法被用来启动新创建的线程,而且start()内部 调用了run()方法,这和直接调用run()方法的效果不一样。当你调用run()方法的时候,只会是在原来的线程中调用,没有新的线程启 动,start()方法才会启动新线程

Thread的主要方法

  • public void start()
    使用该线程开始执行;Java虚拟机调用该线程的run方法
  • public void run()
    如果该线程是使用独立的Runnable运行对象构造的,则调用该Runnable对象的run方法,否则该方法不执行任何操作并返回
  • public final void setName(String name)
    改变线程名称,使之与参数name相同
  • public final void setPriority(int priority)
    更改线程的优先级
  • public final void setDaemon(boolean on)
    将该线程标记为守护线程或者用户线程
  • public final void join(long milisec)
    等待该线程终止的时间最长为millis毫秒
  • public void interrupt()
    中断线程
  • public final boolean isAlive()
    测试线程是否处于活动状态

下面的方法是thread类的静态方法
- public static void yield()
暂停当前正在执行的线程对象,并且执行其他线程
- public static void sleep(long millisec)
在指定的毫秒数内让正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响
- public static Thread cuurentThread()
返回对当前正在执行的线程对象的引用
- public static void dumpStack()
将当前线程的堆栈跟踪打印至标准错误流
- public static boolean holdsLock(Object x)
当且仅当当前线程在指定的对象上保持监视器锁时,才返回true

通过Callable和Future来创建线程

1.创建Callable接口的实现类,并且实现call方法,该call方法将作为线程执行体,并且有返回值
2.创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值
3.使用FutureTask对象作为Thread对象的target创建并且启动线程
4.调用FutureTask对象的get()方法来获得子线程执行结束后的返回值

这个方法我没什么兴趣,有空再学

创建线程的三种方法的对比

采用实现 Runnable 接口的方式创建多线程时,线程类只是实现了 Runnable 接口还可以继承其他类。
使用继承 Thread 类的方式创建多线程时,编写简单,如果需要访问当前线程,则无需使用 Thread.currentThread() 方法,直接使用 this 即可获得当前线程。

线程的几个主要概念

在多线程编程时,你需要了解以下几个概念:
线程同步
线程间通信
线程死锁
线程控制:挂起、停止和恢复

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值