Java线程

进程和线程

进程

进程:进程是计算机中的程序关于某数据集合上的一次运行活动,是系统进行资源分配的基本单位。也就是程序的执行过程。

  • 独立性:每一个进程都有自己的空间,在没有经过进程本身允许的情况下,一个进程不可以直接访问其它的的进程空间。
  • 动态性:进程是动态产生,动态消亡的
  • 并发性:任何进程都可以同其它进程一起并发执行

并行和并发
并行:在同一时刻,有多个指令在多个CPU上【同时】执行

image.png
并发:在同一时刻,有多个指令在单个CPU上【交替】执行
image.png

多进程同时工作:
对于CPU而言,它是多个进程间轮换执行的

线程

线程:进程可以执行多个任务,每个任务就是线程
多线程的意义:

  • 随着处理器的核心数量越来越多,现在大多数计算机都比以往更加擅长并行计算。
  • 一个线程,在一个时刻,只能运行在一个处理器核心上。
  • 提高执行效率。
  • 同时处理多个任务。

image.png

Java默认是多线程

public class ThreadDemo {
   
    /*
        Java程序默认是多线程的, 程序启动后默认会存在两条线程
            1. 主线程
            2. 垃圾回收线程
     */
    public static void main(String[] args) {
   
        Thread mt = new Thread();
        mt.start();

        for (int i = 1; i <= 2000; i++) {
   
            System.out.println("main线程执行了");
        }

        // 制造垃圾
        for (int i = 1; i <= 500000; i++) {
   
            new Demo();
        }

    }
}

class Demo {
   
    @Override
    protected void finalize() throws Throwable {
   
        System.out.println("垃圾被清理了");
    }
}

Java开启线程的方式

继承Thread类

public class ThreadDemo1 {
   
    /*
        开启线程第一种方式: 继承Thread类

        1. 编写一个类继承Thread
        2. 重写run方法
        3. 将线程任务代码写在run方法中
        4. 创建线程对象
        5. 调用start方法开启线程

        细节: 调用start方法开启线程, 会自动的调用run方法执行.

        注意: 只有调用了start方法, 才是开启了新的线程
     */
    public static void main(String[] args) {
   
        // 4. 创建线程对象
        MyThread mt1 = new MyThread();
        MyThread mt2 = new MyThread();
        // 5. 调用start方法开启线程
        mt1.start();
        mt2.start();
    }
}

// 1. 编写一个类继承Thread
class MyThread extends Thread {
   
    // 2. 重写run方法
    @Override
    public void run() {
   
        // 3. 将线程任务代码写在run方法中
        for (int i = 1; i <= 200; i++) {
   
            System.out.println("线程任务执行了" + i);
        }
    }
}

实现Runnable接口

public class ThreadDemo2 {
   
    /*
        开启线程的第二种方式: 实现Runnable接口

        1. 编写一个类实现Runnable接口
        2. 重写run方法
        3. 将线程任务代码写在run方法中
        4. 创建线程任务资源
        5. 创建线程对象, 将资源传入
        6. 使用线程对象调用start方法, 开启线程
     */
    public static void main(String[] args) {
   
        // 4. 创建线程任务资源
        MyRunnable mr = new MyRunnable();
        // 5. 创建线程对象, 将资源传入
        Thread t = new Thread(mr);
        // 6. 使用线程对象调用start方法, 开启线程
        t.start();

        for (int i = 1; i <= 2000; i++) {
   
            System.out.println("main线程执行了");
        }
    }
}

// 1. 编写一个类实现Runnable接口
class MyRunnable implements Runnable {
   
    // 2. 重写run方法
    @Override
    public void run() {
   
        // 3. 将线程任务代码写在run方法中
        for (int i = 1; i <= 200; i++) {
   
            System.out.println("线程任务执行了" + i);
        }
    }
}

实现Callable接口(线程执行完如果有结果产生,并且需要返回值)

public class ThreadDemo3 {
   
    /*
        开启线程的第三种方式: 实现Callable接口

        1. 编写一个类实现Callable接口
        2. 重写call方法
        3. 将线程任务代码写在call方法中
        4. 创建线程任务资源对象
        5. 创建线程任务对象, 封装线程资源
        6. 创建线程对象, 传入线程任务
        7. 使用线程对象调用start开启线程
     */
    public static void main(String[] args) throws Exception {
   
        // 创建线程任务资源对象
        MyCallable mc = new MyCallable();
        // 创建线程任务对象, 封装线程资源
        FutureTask<Integer> task1 = new FutureTask<>(mc);
        FutureTask<Integer> task2 = new FutureTask<>(mc);
        // 创建线程对象, 传入线程任务
        Thread t1 = new Thread(task1);
        Thread t2 = new Thread(task2);
        // 使用线程对象调用start开启线程
        t1.start();
        t2.start();

        Integer result1 = task1.get();
        Integer result2 = task2.get();
        System.out.println("task1获取到的结果为:" + result1);
        System.out.println("task2获取到的结果为:" + result2);

    }
}

// 1. 编写一个类实现Callable接口
class MyCallable implements Callable<Integer> {
   
    // 2. 重写call方法
    @Override
    public Integer call() throws Exception {
   
        // 3. 将线程任务代码写在call方法中
        int sum = 0;
        for (int i = 1; i <= 100; i++) {
   
            sum += i;
            System.out.println("sum=" + sum);
        }
        return sum;
    }
}

image.png

线程相关方法

方法名称 说明
String getName() 返回此线程的名称
void setName(String name) 设置线程的名字(构造方法也可以设置名字)
static Thread currentThread() 获取当前线程的对象
static void sleep(long time) 让线程休眠指定的时间,单位为毫秒
setPriority(int newPriority) 设置线程的优先级
final int getPriority() 获取线程的优先级
final void setDaemon(boolean on) 设置为守护线程

与线程名有关的方法

String getName() 返回此线程的名称
void setName(String name) 设置线程的名字(构造方法也可以设置名字)
**static **Thread currentThread() 获取当前线程的对象
public class ThreadMethodDemo01 {
   
    /**
     * 开启线程第一种方式:继承Thread类
     * 1.编写一个类继承Thread
     * 2.重写run方法
     * 3.将线程任务代码写在run方法中
     * 4.创建线程对象
     * 5.调用start方法开启线程
     * 细节:调用start方法开启线程,会自动调用run方法执行
     * <p>
     * Thread类的方法:
     * public String getName():获取线程名字
     * public void setName():设置线程名字
     * public static Thread currentThread():获取当前线程的对象
     */

    public static void main(String[] args) {
   
        // 4.创建线程对象
        MyThread1 myThread11 = new MyThread1("A:");
        MyThread1 myThread12 = new MyThread1("B:");

        //        myThread11.setName("Cammy:");
        //        myThread12.setName("Lee:");

        // 5.调用start方法开启线程
        myThread11.start();
        myThread12.start();
    }
}

// 1.编写一个类继承Thread
class MyThread1 extends Thread {
   

    public MyThread1() {
   
    }

    public MyThread1(String name) {
   
        super(name);
    }

    // 2.重写run方法
    @Override
    public void run() {
   
        // 3.将线程任务代码写在run方法中
        for (int i = 0; i <= 200; i++) {
   
            System.out.println(super.getName() + " 线程任务执行了 " + i);
        }
    }
}
public class ThreadMethodDemo02 {
   
    /*
            开启线程的第二种方式:实现Runnable接口

            1.编写一个类实现Runnable接口
            2.重写run
            3.将线程任务方法写在run方法中
            4.创建线程任务资源
            5.创建线程对象,将资源传入
            6.使用线程对象调用start,开启线程
     */
    public static void main(String[] args) {
   
        // 4.创建线程任务资源
        MyRunnable1 myRunnable = new MyRunnable1();
        // 5.创建线程对象,将资源传入
        Thread t = new Thread(myRunnable, "线程A:");
        // 6.使用线程对象调用start,开启线程
        t.start();

        for (int i = 0; i <= 2000; i++) {
   
            System.out.println(Thread.currentThread().getName() + "线程被执行了");
        }
    }
}

// 1.编写一个类实现Runnable接口
class MyRunnable1 implements Runnable {
   

    // 2.重写run
    @Override
    public void run() {
   
        // 3.将线程任务方法写在run方法中
        int sum = 0;
        for (int i = 0; i <= 200; i++) {
   
            sum += i;
            System.out.println(Thread.currentThread().getName() + "线程任务执行了" + i);
        }
    }
}
public class ThreadMethodDemo03 {
   
    /*
        开启线程的第三种方式,实现Callable接口

        1.编写一个类实现Callable接口
        2.重写call方法
        3.将线程任务代码写在call方法中
        4.创建线程任务资源对象
        5.创建线程任务对象,封装线程资源
        6.创建线程对象,传入线程任务
        7.使用线程对象调用start开启线程
     */
    public static void main(String[] args) throws ExecutionException, InterruptedException {
   
        // 创建线程任务资源对象
        MyCallable1 myCallable = new MyCallable1();
        // 创建线程任务对象,封装线程资源
        FutureTask<Integer> task = new FutureTask<>(myCallable);
        FutureTask<Integer> task1 = new FutureTask<>(myCallable);
        // 创建线程对象,传入线程任务
        Thread thread = new Thread(task, "线程A:");
        Thread thread1 = new Thread(task1, "线程B:");
        // 使用线程对象调用start开启线程
        thread.start();
        thread1.start();

        // 线程开起来了才能拿到结果
        Integer result = task.get();
        Integer result1 = task1.get();
        System.out.println(thread.getName() + "获取到的结果为:" + result);
        System.out.println(thread1.getName() + "获取到的结果为:" + result1);
    }
}

// 1.编写一个类实现Callable接口
class MyCallable1 implements Callable {
   

    // 2.重写call方法
    @Override
    public Object call() throws Exception {
   
        // 3.将线程任务代码写在call方法中
        int sum = 0;
        for (int i = 0; i <= 100; i++) {
   
            sum += i;
            System.out.println(Thread.currentThread().getName() + "sum = " + sum);
        }
        return sum;
    }
}

与线程休眠时间有关的方法

**static **void sleep(long time) 让线程休眠指定的时间,单位为毫秒
public class ThreadMethodDemo04 {
   
    /*
        休眠线程的方法
            public static void sleep(long time):让线程休眠指定的时间,单位为毫秒
     */

    public static void main(String[] args) throws InterruptedException {
   
        for (int i = 5; i >= 0; i--) {
   
            System.out.println("倒计时: " + i + " seconds");
            Thread.sleep(1000);
        }
    }
}

与线程优先级有关的方法

setPriority(int newPriority) 设置线程的优先级
final int getPriority() 获取线程的优先级

线程的调度方式

  • 抢占式调度(随机)
  • 非抢占式调度(轮流使用)
public class ThreadMethodDemo05 {
   
    /*
        线程优先级的方法:(只是能提高某一个线程抢到cpu的概率)
            抢占式调度
            public setPriority(int newPriority):设置线程优先级
            public final int getPriority:获取线程优先级

            优先级 1~10 (默认5)
     */

    public static void 
  • 27
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值