javase-thread-210201-01

javase-thread-210201-01

  • 简介
  • 创建线程
  • 练习
  • 静态代理模式

简介

  • 线程实现
  • 线程状态
  • 线程同步
  • 线程通信问题

操作系统中运行的程序就是进程,一个进程可以有多个线程

程序是指令和数据的有序集合,其本身没有任何运行的含义,是一个静态的概念

进程是执行程序的一次执行过程,它是一个动态的概念。是系统资源分配的单位

通常在一个进程中可以包含若干个线程,一个进程中至少有一个线程(主线程),不然没有意义。线程是CPU调度和执行的单位。

注:很多线程是模拟出来的,真正的多线程是指由多个cpu,即多核,如服务器。如果是模拟出来的多线程,即在一个cpu的情况下,在同一个时间点,cpu只能执行一个代码,因为切换很快,所以就有同时执行的错局。

  • 线程就是独立的执行路径
  • 在程序运行时,即使没有自己创建的线程,后台也会有多个线程,如主线程,gc线程
  • main()称主线程,为系统的入口,用于执行整个程序
  • 在一个进程中,如果开辟了多个线程,线程的运行由调度器安排调度,调度器是与操作系统紧密相关的,先后顺序是不能人为干预的
  • 对同一份资源进行操作时,会存在资源抢夺问题,需要加入并发控制
  • 线程会带来额外的开销,如cpu调度时间,并发控制开销
  • 每个线程在自己的工作内存交互,内存控制不当会造成数据不一致

创建线程

1.Thread(类)
//继承Thread类
/*
	步骤:
		1.自定义线程类,继承Thread类
		2.重写run()方法,编写线程执行体
		3.创建线程对象,调用start()方法启动线程
*/

//线程开启不一定立即执行,由cpu调度执行
package bgy210310;

public class Demo01 extends Thread{

    // 重写 run() 方法
    @Override
    public void run(){
        for (int i = 0; i < 100; i++) {

            // 修改线程名称
            Thread.currentThread().setName("线程一");

            System.out.println("当前线程为" + Thread.currentThread().getName());

            // 线程睡眠
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {

        // 创建线程对象
        Demo01 demo01 = new Demo01();
        // 开启线程
        demo01.start();


        // 主线程
        for (int i = 0; i < 100; i++) {

            // 修改线程名称
            Thread.currentThread().setName("主线程");

            System.out.println("当前线程为" + Thread.currentThread().getName());
        }
    }
}

2.Runnable(接口)
/*
    1.定义Demo02类实现Runnable接口
    2.实现run()方法
    3.创建线程对象,调用start()方法,启动线程
*/

public class Demo02 implements Runnable{

    @Override
    public void run() {
        for (int i = 0; i < 100; i++) {

            // 修改线程名称
            Thread.currentThread().setName("线程一");

            System.out.println("当前线程为" + Thread.currentThread().getName());

            // 线程睡眠
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public static void main(String[] args) {
//        Demo02 demo02 = new Demo02();
//        Thread thread = new Thread(demo02);       // 代理模式
//        thread.start();

//        Thread thread = new Thread(new Demo02());
//        thread.start();

        // 创建线程并启动
        new Thread(new Demo02()).start();

        // 主线程
        for (int i = 0; i < 100; i++) {

            // 修改线程名称
            Thread.currentThread().setName("主线程");

            System.out.println("当前线程为" + Thread.currentThread().getName());
        }
    }
}

3.Callable(接口)
/*
    1.实现 Callable 接口
    2.重写call方法,,需要抛出异常,并且需要一个返回值
    3.创建目标对象
    4.创建执行服务     ExecutorService service = Executors.newFixedThreadPool();
    5.提交执行        Future<Boolean> r = service.submit();
    6.获取结果        boolean rs = r.get();
    7.关闭服务        service.shutdown();
 */

public class Demo03 implements Callable<Boolean> {
    @Override
    public Boolean call() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println("当前线程为" + Thread.currentThread().getName());

            // 线程睡眠
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        return true;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        // 创建目标对象
        Demo03 demo03_01 = new Demo03();
        Demo03 demo03_02 = new Demo03();

        // 创建执行服务
        // 参数是 你想有几个线程,就来几个,我目前是2个线程,,就是2
        ExecutorService service = Executors.newFixedThreadPool(2);

        // 提交执行
        Future<Boolean> r1 = service.submit(demo03_01);
        Future<Boolean> r2 = service.submit(demo03_02);

        // 获取结果
        boolean rs1 = r1.get();
        boolean rs2 = r2.get();

        // 关闭服务
        service.shutdown();
    }
}

练习

买票问题
/*
	出现问题:
		多个线程操作同一个资源的情况下,出现了线程不安全
*/

public class Demo04 implements Runnable{
    // 目前有30张票
    public int numTicket = 30;

    @Override
    public void run() {
        while (true){
            if(numTicket <= 0){
                System.out.println("票以售空");
                break;
            }

            // 模拟买票延时
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

            System.out.println(Thread.currentThread().getName() + "拿到第" + numTicket-- + "张票");
        }
    }

    public static void main(String[] args) {
        Demo04 demo04 = new Demo04();
        new Thread(demo04,"小明").start();
        new Thread(demo04,"王刚").start();
        new Thread(demo04,"黄牛").start();
    }
}

龟兔赛跑
public class Demo05 implements Runnable{
    private int distance = 100;
    private String winner;

    @Override
    public void run() {
        for (int i = distance; i >= 0; i--) {

            // 模拟兔子休息
            if(Thread.currentThread().getName().equals("兔子")){
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

            // 判断比赛是否结束
            boolean flag = isOver(i);
            if (flag){
                break;
            }

            System.out.println(Thread.currentThread().getName() + "还剩" + i + "米");
        }
    }

    // 判断是否跑完路程
    public boolean isOver(int distance){
        // 已经存在获胜者
        if (winner != null){
            return true;
        }
        if (distance <= 0){
            winner = Thread.currentThread().getName();
            System.out.println(winner + "获胜");
            return true;
        }

        return false;
    }

    public static void main(String[] args) {
        Demo05 demo05 = new Demo05();
        new Thread(demo05,"兔子").start();
        new Thread(demo05,"乌龟").start();
    }
}

静态代理模式

package bgy210310;

/*
    1.真实对象和代理对象都要实现同一个接口
    2.代理对象要代理真实角色
    
    优点:
    	1.代理对象可以做很多真实对象做不了的事情
    	2.真实对象专注做自己的事情
 */

interface Wedding{
    void happyWedding();
}

// 真实角色,,,谁要结婚
class You implements Wedding{
    @Override
    public void happyWedding() {
        System.out.println("白光一要结婚了,很高心");
    }
}

// 代理角色,,,表示婚庆公司,来个你安排婚礼,帮助你结婚
class WeddingCompany implements Wedding{

    // 真实角色
    private Wedding target;

    public WeddingCompany(Wedding target){
        this.target = target;
    }

    @Override
    public void happyWedding() {
        before();
        this.target.happyWedding();     // 真实角色
        after();
    }

    private void after() {
        System.out.println("结婚之后,婚庆公司拿钱,撤散现场");
    }

    private void before() {
        System.out.println("结婚之前,婚庆公司策划婚礼,布置现场");
    }

}

public class Demo06 {
    public static void main(String[] args) {
        WeddingCompany weddingCompany = new WeddingCompany(new You());
        weddingCompany.happyWedding();
    }
}
private void after() {
    System.out.println("结婚之后,婚庆公司拿钱,撤散现场");
}

private void before() {
    System.out.println("结婚之前,婚庆公司策划婚礼,布置现场");
}

}

public class Demo06 {
public static void main(String[] args) {
WeddingCompany weddingCompany = new WeddingCompany(new You());
weddingCompany.happyWedding();
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值