Java学习记录day20-线程

多线程的概述。

什么是进程?
程序是静止的,运行中的程序就是进程。
进程的三个特点:
1.动态性:进程动态的占用主机中的内存,CPU , 网络 , 磁盘等处理自己的功能。
2.并发性:
假如一个服务器只有一个CPU,而CPU是单核的。
那么同一个时刻其实只有一个进程在被CPU执行,
CPU会分时轮询切换的为每个进程服务,给我们的感觉好像这些进程在同
时执行一样 这就是进程的并发。(抢占式并发)。
进程的执行会出现随机性。
并发:在同一个时刻只有一个进程在执行(针对单核)
并行: 同一个时刻多个进程在同时执行!
3.独立性:
进程都有自己独立的内存区域,互相之间的执行是不会干扰的。
什么是线程?
线程属于进程的。
一个进程可以包含多个线程,这就是多线程。
线程的特点:
动态性:线程也要动态的占用内存,CPU…
并发性:多个线程会并发抢占CPU执行自己。
多线程的优势:
线程消耗的资源比进程小,开销小于进程。
多线程可以提高程序的效率。
多线程可以设计很好的业务模型,有时候还必须要用多线程。
小结:
线程属于进程
多线程是并发执行的,所以多个线程抢占CPU执行会出现随机性执行!!
线程的创建有三种方式;
方式一:
步骤:通过继承Thread,重写run()方法!调用start方法
优点:编码简单。
缺点:线程类已经继承了Thread类,无法再继承其他类 ,本身的功能就不够强大。
不适合做线程池,不能得到线程执行的结果。

public class ThreadDemo01 {
    // 进程:ThreadDemo01
    // 主线程:main方法。
    public static void main(String[] args) {
        // 创建一个子线程
        MyThread t = new MyThread();
        // 线程启动必须用start方法,如果用run方法,就失去了线程特征。
        t.start();
        for (int i = 0 ; i < 5 ; i++ ){
            System.out.println("main线程输出:"+i);
        }
    }
}
// 线程类,线程类适用于创建线程的
class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0 ; i < 5 ; i++ ){
            System.out.println("子线程输出:"+i);
        }
    }
}

方式二:Runnable接口
步骤:
(1)定义一个线程任务类实现Runnable接口。
(2)重写run()方法。
(3)创建线程任务类对象,创建一个Thread线程对象包装线程任务对象。
(4)启动线程对象。
创建方式二的优缺点:
缺点:编码相对复杂,不能得到线程执行的结果。
优点:线程任务对象只是实现了Runnable接口,可以继续继承其他类,
可以继续实现其他接口。
线程任务对象的本身的功能可以增强,
非常适合做线程池。
非常适合做共享资源的访问。

public class ThreadDemo01 {
    // 进程:ThreadDemo01
    // 主线程:main方法。
    public static void main(String[] args) {
        // 创建一个子线程
        MyThread t = new MyThread();
        // 线程启动必须用start方法,如果用run方法,就失去了线程特征。
        t.start();

        for (int i = 0 ; i < 5 ; i++ ){
            System.out.println("main线程输出:"+i);
        }

    }
}
// 线程类,线程类适用于创建线程的
class MyThread extends Thread{
    @Override
    public void run() {
        for (int i = 0 ; i < 5 ; i++ ){
            System.out.println("子线程输出:"+i);
        }

方式三:Callable接口
步骤:
(1)创建一个线程任务对象,实现Callable接口,申明线程执行的结果类型。
重写call方法。
(2)创建一个未来任务对象FutureTask对象,包装Callable实现类对象。
(3)创建一个线程对象Thread来包装FutureTask对象
(4)启动线程。
(5)获取线程执行的结果。

创建方式三的优缺点:
缺点:编码复杂。
优点:
线程任务对象只是实现了Callable接口,可以继续继承其他类,
可以继续实现其他接口。
线程任务对象的本身的功能可以增强,
非常适合做线程池。
非常适合做共享资源的访问。
可以得到线程执行的结果!

public class ThreadDemo01 {
    public static void main(String[] args) {
        // (2)创建一个未来任务对象FutureTask对象,包装Callable实现类对象。
        CallableTarger targer = new CallableTarger();
        //  未来任务对象的功能:可以在线程执行完毕以后得到线程的执行结果。
        //  未来任务对象实际上就是一个Runnable对象
        FutureTask<String> task = new FutureTask<>(targer);
        // public Thread(Runnable task)
        // (3)创建一个线程对象Thread来包装FutureTask对象
        Thread t = new Thread(task);
        // (4)启动线程。
        t.start();

        for(int i = 1 ; i <= 5 ; i++ ){
            System.out.println(Thread.currentThread().getName()+"=>输出:"+i);
        }

        // (5)获取线程执行的结果。
        try {
            String rs = task.get();
            System.out.println(rs);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
//  (1)创建一个线程任务对象,实现Callable接口,申明线程执行的结果类型。
// 需求:让线程求和,求 1-5的和返回。
class CallableTarger implements Callable<String>{
    @Override
    public String call() throws Exception {
        int sum = 0 ;
        for(int i = 1 ; i <= 5 ; i++ ){
            sum+=i;
            System.out.println(Thread.currentThread().getName()+"=>输出:"+i);
        }
        return Thread.currentThread().getName()+"求和返回:"+sum;
    }
}

线程同步:为了解决线程安全问题
首先了解一下线程安全,在多个线程在操作同一个共享资源的时候,可能出现线程安全问题。 线程同步的思想是:让共享资源的访问实现先后访问。
核心点:把出现线程安全问题的代码给锁起来,每次只能有一个线程访问
其他线程必须等待这个线程执行完毕以后才可以进来访问。
线程同步的方式:

(1)同步代码块:synchronized关键字 按照规范:建议实例方法用this作为锁。
                                静态方法用字节码作为锁:类名.class。
(2)同步方法:在方法名上加synchronized关键字修饰
(3)lock锁:lock锁:
 自己写一个锁:创建ReentrantLock对象
     - public void lock() `:加同步锁。
     - `public void unlock()`:释放同步锁。一般可以配合try(){}catch{}finally()使用。

线程控制
一般有start、run、sleep方法还有isAlive、currentThread、interrupt等方法。
线程状态:
image.png

线程一般有六个状态:新建—运行-阻塞-定时等待-等待-结束

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值