多线程(第十二天):进程,线程,多线程实现,同步与异步,线程池;

本文介绍了进程的基本概念,包括独立性、动态性和并发性,并对比了程序与进程的不同。接着详细讨论了线程的三态模型及两种实现方式(继承Thread和实现Runnable)。重点讲解了同步与异步,以及如何使用synchronized关键字确保数据安全。最后,剖析了线程池的使用,如Executors工具类在创建固定线程池的应用实例。

一,进程

正在运行的程序.

特点

        独立性:京城是系统中独立存在的实体,它拥有自己独立的资源

        动态性:进程与程序的区别在于,程序知识一个静态的指令集合,而进程是一个证在系统中活动的指令(程序是静态的,进程是动态的

        并发性:多个进程可以在单个CPU上并发执行,多个进程之间不会互相影响。

二,线程

线程的三态模型

 三,多线程实现

①方案实现一:继承Thread

public class Demo1  {
    public static void main(String[] args) {
        MyThread s1 = new MyThread("小明");
        MyThread s2 = new MyThread("李华");
        /*s1.run();
        s2.run();*/
        s1.start();
        s2.start();
    }
}
//自定义多线程类:通过Thread
class MyThread extends Thread{
    public MyThread(){
        super();
    }
    public MyThread(String name){
        super(name);
    }
    //重写run()方法:
    @Override
    public void run() {
        //super.run();
        //写自己的业务
        for(int i=0;i<10;i++)
        {
            System.out.println(i+"="+getName());
        }
    }
}

②方案实现二:实现Runnable

public class Demo2 {
    public static void main(String[] args) {
       MyRunnable m1 =new MyRunnable();
       MyRunnable m2 =new MyRunnable();
       Thread m3 = new Thread(m1);
       Thread m4 = new Thread(m2);
       m3.start();
       m4.start();
    }
}
class MyRunnable implements Runnable{
    @Override
    public void run() {
        //业务
        for (int i=0;i<10;i++){
            System.out.println(i+Thread.currentThread().getName());
        }
    }
}

面试题

1,什么是进程?什么是程序?有什么区别

程序:数据与指令的集合,程序是静态的

进程:给程序假日了时间的概念,不同的时间进程有不同的状态

进程是动态的,就代表OS正在运行的程序

独立性,动态性,并发性

2,什么是并行?什么是并发?

CPU:电脑的核心处理器,类似于“大脑”

并发:相对于来说资源比较充足,多个CPU可以同时处理不同的进程

并发:相对于来说资源比较紧缺,多个进程同时抢占公共资源,比如CPU

3方案二的好处

耦合性不强,没有继承,后续仍可以继承

应用:售票业务

一,Thread方法

public class Demo03 {
    public static void main(String[] args) {
        TickDemo td1 = new TickDemo();
        TickDemo td2 = new TickDemo();
        TickDemo td3 = new TickDemo();
        td1.start();
        td2.start();
        td3.start();
    }
}
class TickDemo extends Thread{
    //静态资源属于类资源,被全局所有对象所共享,值只有一份
    static int tick=100;
    @Override
    public void run() {
        try {
            /*
            * 本方法是让线程进行休眠的方法,参数为毫秒,此处休眠10ms
            * 如果线程在休眠后仍然出现问题,才能说明线程在各种状态切换下
            * 不会出现tickets票数数据安全的问题,这样才是比较好的测试
            * */
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        while(true){
            System.out.println(getName()+"="+tick--);
            if (tick<=0){
                break;
            }
        }
    }
}

二,Runnable方法

public class Demo4 {
    public static void main(String[] args) {
        TicketDemo td =new TicketDemo();
        Thread t1 = new Thread(td);
        Thread t2 = new Thread(td);
        Thread t3 = new Thread(td);
        t1.start();
        t2.start();
        t3.start();
    }
}
class TicketDemo implements Runnable{
   int ticket =100;
    @Override
    public void run() {
        try {
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        /*即使是实现接口的方式,还是会出现数据安全的隐患*/
        while (true){
            System.out.println(Thread.currentThread().getName()+"="+ticket--);
            if (ticket<=0) break;//如果if后的执行语句只有一句,大括号{}可以省略不写
        }
    }
}

 四,同步与异步

        同步:体现了排队的效果,同一时刻只能有一个线程独占资源,其他没有权力的线程排队。

                        坏处就是效率底,不过保证了安全

        异步:体现了多线程抢占资源的效果,线程间互补等待,互抢资源

                        坏处就是有安全隐患,不过效率要高些

        synchronized关键字(既可以修饰属性,也可以修饰方法)

同步的前提:

        同步需要两个或者两个以上的线程

        多个线程必须使用同一个锁

Runnable:

public class TestRunnable {
    public static void main(String[] args) {
        Ticket target =new Ticket();
        Thread t1 = new Thread(target);
        Thread t2 = new Thread(target);
        Thread t3 = new Thread(target);
        t1.start();
        t2.start();
        t3.start();
    }
}
/*多线程中出现数据安全问题的原因:多线程程序+共享数据+多条语句操作共享数据*/
/*同步锁:相当于给容易出现问题的代码加了一把锁,包裹了所有可能数显数据安全问题的代码
加锁之后,就有了同步(排队)的效果,但是锁的话,需要考虑:
    锁的范围:不能太大,太大,干啥都得排队。也不能太小,锁不住,还是会有安全隐患
* */
//synchronized (锁对象){会出现安全隐患的所有代码}
class Ticket implements Runnable{
    Object o = new Object();
    int ticket =100;
    @Override
    public void run() {
        synchronized (o) {
            if (ticket > 0) {//在还有票的情况下再卖,解决负数票问题
                /*即使是实现接口的方式,还是会出现数据安全的隐患*/
                while (true) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "=" + ticket--);
                    if (ticket <= 0) break;//如果if后的执行语句只有一句,大括号{}可以省略不写
                }
            }
        }
    }
}

 Thread:

public class Demo05 {
    public static void main(String[] args) {
        TicketDo t1 =new TicketDo();
        TicketDo t2 =new TicketDo();
        TicketDo t3 =new TicketDo();
        TicketDo t4 =new TicketDo();
        t1.start();
        t2.start();
        t3.start();
        t4.start();
    }
}
class TicketDo extends Thread{
    static int ticket =100;
    @Override
    public void run() {
            synchronized (TicketDo.class) {
                if (ticket>0) {
                try {
                    Thread.sleep(10);//让线程休眠,增加线程休眠状态切换的频率
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                /*即使是实现接口的方式,还是会出现数据安全的隐患*/
                while (true) {
                    System.out.println(getName() + "=" + ticket--);
                    if (ticket <= 0) break;//如果if后的执行语句只有一句,大括号{}可以省略不写
                }
            }
        }
    }
}

五,线程池

Executors:辅助创建线程池的工具类 

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Demo06 {
    public static void main(String[] args) {
        Ticket2 target = new Ticket2();
        ExecutorService pool = Executors.newFixedThreadPool(5);
        for (int i=0;i<5;i++){
            pool.execute(target);
        }
    }
}
/*多线程中出现数据安全问题的原因:多线程程序+共享数据+多条语句操作共享数据*/
/*同步锁:相当于给容易出现问题的代码加了一把锁,包裹了所有可能数显数据安全问题的代码
加锁之后,就有了同步(排队)的效果,但是锁的话,需要考虑:
    锁的范围:不能太大,太大,干啥都得排队。也不能太小,锁不住,还是会有安全隐患
* */
//synchronized (锁对象){会出现安全隐患的所有代码}
class Ticket2 implements Runnable{
    Object o = new Object();
    int ticket =100;
    @Override
    public void run() {
        synchronized (o) {
            if (ticket > 0) {//在还有票的情况下再卖,解决负数票问题
                /*即使是实现接口的方式,还是会出现数据安全的隐患*/
                while (true) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println(Thread.currentThread().getName() + "=" + ticket--);
                    if (ticket <= 0) break;//如果if后的执行语句只有一句,大括号{}可以省略不写
                }
            }
        }
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员慕慕

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值