进程和线程

进程

程序是对数据描述与操作的代码的集合
进程是程序的一次动态执行过程,它对应了从代码的加载、执行至执行完毕的一个完整过程
进程的特点

  • 进程是系统运行程序的基本单位
  • 每一个进程都有自己一个独立的内存空间、一组系统资源
  • 每一个进程的内部数据和状态都是完全独立的

线程

线程是进程中执行运算的最小单位,一个进程在其执行过程中可以产生多个线程,而线程必须在某个进程内执行
一个进程中同时运行了多个线程,用来完成不同的工作,则称之为多线程
线程特点

  • 一个进程中至少要有一个线程
  • 资源分配给进程,同一进程中所有线程共享该进程所有资源
  • 真正在处理机上运行的是线程

多线程的优点

  • 多线程程序可以带来更好的用户体验
  • 多线程可以最大限度的提高计算机系统的利用效率

线程类

每个程序至少自动拥有一个线程,称为主线程。程序中的 public static void main() 方法就是主线程的入口,运行 Java 程序时,会先执行这个主方法
使用线程步骤
(1)定义一个线程
(2)创建线程对象
(3)启动线程
(4)关闭线程

使用 Thread 类创建线程

Java 提供了 java.lang.Thread 类支持多线程编程,该类提供了大量的方法来控制和操作线程
Thread 类的常用方法

方法说明
void run()执行任务操作的方法
void start()使该线程开始执行
void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)
String getName返回该线程的名称
int getPriority()返回线程的优先级
void setPriority(int newPriority)更改线程的优先级
Thread.State getState()返回该线程的状态
boolean isAlive()测试线程是否处于活动状态
void join()等待该线程终止
void interrupt()中断线程
void yieid()暂停当前正在执行的线程对象,并执行其他线程

创建进程步骤
1、定义一个类并继承 Thread 类,重写 run() 方法,在 run() 方法中实现数据输出
2、创建进程对象
3、调用 start() 方法启动线程

例如:在线程中输出1到100的整数

public class Mm extends Thread {
    public static void main(String[] args) {
        Mm a=new Mm();
        a.start();
    }

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            System.out.println(i);
        }
    }
}
使用 Runnable 接口创建线程

上面介绍的使用 Thread 类的方式创建线程简单明了,但它也有一个缺陷就是,如果已经定义的类继承了其他类则无法再继承 Thread 类;而 Runnable 接口创建线程就可以很好的解决这一问题
Runnable 接口中声明了一个 run() 方法,一个类可以通过实现 Runnable 接口并重写 run() 方法完成线程的所有活动
已实现的 run() 方法称为该对象的线程体;任何实现 Runnable 接口的对象都可以作为一个线程的目标对象

代码演示
使用 Runnable 接口的方式创建线程,在线程中输出1到100的整数

public class Mm implements Runnable {
    public static void main(String[] args) {
        Mm a=new Mm();
        Thread t=new Thread(a,"线程a");
        t.start();
    }

    @Override
    public void run() {
        for (int i = 1; i <= 100; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
使用 Callable 类创建线程
public class TestCallable implements Callable<Integer> {
    @Override
    public Integer call() throws Exception {
        for (int i = 0; i < 10; i++) {
            System.out.println(Thread.currentThread().getName()+":"+(i+1));
        }
        return 3;
    }

    public static void main(String[] args) throws Exception {
        TestCallable t=new TestCallable();
        FutureTask<Integer> f=new FutureTask<Integer>(t);
        Thread th=new Thread(f);
        th.start();
        System.out.println(f.get());
    }
}

线程状态

在这里插入图片描述
线程一般分为五个状态:创建状态、就绪状态、运行状态、阻塞状态、死亡状态
1.创建状态:指调用 start() 方法之前,刚创建的状态
2.就绪状态:指调用 start() 方法之后,等待系统分配CPU资源的状态
3.运行状态:指线程运行过程,即执行操作代码块
4.阻塞状态:指线程运行过程中出现一些特殊情况使线程无法继续运行,即进入阻塞状态
5.死亡状态:指程序运行结束

线程调度

当同一时刻有多个线程处于可运行状态,它们需要排队等待CPU分配资源,每个线程会自动获得一个线程的优先级,优先级的高低反映线程任务的重要或紧急程度;可运行状态的线程按优先级高低排队
线程调度是抢占式调度,即当前线程执行过程中,如果有一个优先级更高的线程进入可运行状态,则这个更高优先级的线程立即被调度执行

线程优先级
线程优先级用1~10表示,优先级依次增高,默认值是5,每个优先级对应一个 Thread 类的共用静态常量;
public static final int NORM_PRIORITY=5;
public static final int MIN_PRIORITY=1;
public static final int MAX_PRIORITY=10;
线程优先级可以通过 setPriority(int grade) 方法更改

实现线程调度的方法
1、join() 方法
该方法使当前线程暂停执行,等待调用该方法的线程结束后再继续执行本线程
(1)定义线程类,输出5次当前线程名称
(2)定义测试类,使用 join() 方法阻塞主线程
线程类

public class MyThread extends Thread {
    public MyThread(String name){
        super(name);
    }

    @Override
    public void run() {
        for (int i = 0; i < 5; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

测试类

public class Test {
    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            if (i==5){
                MyThread m=new MyThread("线程1");
                try {
                    m.start();
                    m.join();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}

运行结果
在这里插入图片描述
上面示例中,使用 join() 方法阻塞指定的线程直到另一个线程完成以后再继续执行

2、sleep() 方法
sleep() 方法会让当前线程睡眠 millis 毫秒,线程由运行中的状态进入不可运行状态,睡眠时间过后再次进入可运行状态,其语法格式如下

public static void sleep(long millis)

示例

public class Wait {
    public static void bySec(long s){
        for (int i = 0; i < s; i++) {
            System.out.println(i+1+"秒");
            try {
                Thread.sleep(1000);//睡眠1秒
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
        System.out.println("Wait");
        Wait.bySec(5);
        System.out.println("start");
    }
}

运行结果
在这里插入图片描述
这里在执行主线程以后,首先输出 Wait ,然后主线程等待5秒后继续执行

3、yield() 方法
yield() 方法可以让当前线程暂停执行,允许其他线程执行,但该线程仍处于可运行状态,并不变为阻塞状态。此时,系统选择其他相同或更高优先级线程执行,若无其他相同或更高优先级线程,则该线程继续执行,其语法格式如下

public static void yield()
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值