Java基础复习-多线程

Java基础复习-多线程

本文仅对学习过程中所缺java知识点的查缺补漏复习

多线程

  • 程序(program):为了完成特定任务,用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象;
  • 进程(process):程序的一次执行过程,或是正在运行的一个程序。是一个动态的过程:有自身的产生、存在和消亡的过程-生命周期;
    1. 程序是静态的,进程是动态的;
    2. 进程作为资源分配的单位,系统在运行时会为每个进程分配不同的内存区域;
  • 线程(thread):进程可以进一步细化为线程,是一个程序内部的一条执行路径。
    1. 若一个进程同一时间并行执行多个线程,就是支持多线程的;
    2. 线程作为调度和执行的单位,每个线程拥有独立的运行栈和程序计数器(pc),线程切换的开销小;
    3. 一个进程中的多个线程共享相同的内存单元/内存地址空间----->它们从同一堆中分配对象,可以访问相同的变量和对象。这就使得线程间通信更简便、高效。但多个线程操作共享的系统资源可能就带来安全隐患;

一个Java应用程序java.exe,至少有三个线程:main()主线程、gc()垃圾回收线程、异常处理线程。但是如果发生了异常,是会影响主线程的;

并行和并发

  • 并行:多个CPU同时执行多个任务。比如:多个人同时做不同的事。
  • 并发:一个CPU(采用时间片)同时执行多个任务。比如:秒杀、多个人做同一件事。

Java中多线程的使用

多线程的创建1:继承Thread类

方式1:继承于Thread

  • 1.创建一个继承于Thread类的子类
  • 2.重写Thread类的run()方法:新线程要执行的操作
  • 3.创建Thread类子类的对象
  • 4.通过对象调用start()方法:启动当前新线程;JVM调用当前线程的run()方法
  • 注意:这里需要调用start()方法,不能直接调用run()方法,调用run()方法虽然不会报错,但是跟普通的对象调用方法就没区别了,就不会开启多线程。
  • 如果需要再开启同一子类的第二个线程,需要重新new一个子类对象,不能用原来new好的子类对象去再次调用start()方法,不然会抛一个违法线程状态异常
public class MyThread extends Thread {
   

    @Override
    public void run() {
   
        for (int i=0;i<100;i++)
            if (i % 5 == 0)
                System.out.println(i);
    }
}
public class ThreadTest {
   
    public static void main(String[] args){
   
        MyThread myThread = new MyThread();
        myThread.start();
        for (int i=0;i<100;i++)
            if (i % 5 != 0)
                System.out.println("main:"+i);
    }
}
Thread方法

Thread中的常用方法:

  1. start():启动当前线程,调用当前线程的run()
  2. run():通常需要重写Thread类中的此方法,将创建的线程要执行的操作声明在此方法中;
  3. currentThread():静态方法,返回执行当前代码的线程;
  4. etName():获取当前线程的名字;
  5. setName():设置当前线程的名字;
  6. yield():释放当前cpu的执行权,但是执行权可能下一刻还是轮到当前线程;
  7. join():在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a才结束阻塞状态;
  8. sleep(long millis):单位毫秒,令当前活动线程在指定时间段内放弃对CPU控制,使其它线程有机会被执行,时间到后重排队;
  9. isAlive():判断当前线程是否还活着。
线程优先级
  • MAX_PRIORITY:10(最高线程优先级)
  • MIN_PRIORITY:1(最低线程优先级)
  • NORM_PRIORITY:5(默认线程优先级)
  • getPriority():获取当前线程优先级;
  • setPriority(int p):设置当前线程优先级
  • 优先级的设置在线程启动之前;
  • 优先级高只是比较高概率会被执行,但不是高优先级的执行完才会执行低优先级的;
例子
三个窗口卖票1
/**
*	虽然下面这种方式可以模拟三个窗口卖100张票的场景,
*	但是可能会出现并发,线程不安全,后面将会改进,
*	这里的代码旨在模拟多线程
**/
public class Window extends Thread {
   

    private static int ticket = 100;

    @Override
    public void run() {
   
        while(true){
   
            if(ticket > 0)
                System.out.println(getName() + ":" + ticket--);
            else
                break;
        }
    }

    public static void main(String[] args){
   
        Window window1 = new Window();
        Window window2 = new Window();
        Window window3 = new Window();

        window1.setName("线程1");
        window2.setName("线程2");
        window3.setName("线程3");
        window1.start();
        window2.start();
        window3.start();
    }
}
多线程的创建2:实现Runnable接口
  1. 创建一个实现了Runnable接口的类;
  2. 实现类去实现Runnable中的抽象方法:run()
  3. 创建实现类的对象;
  4. 将此对象作为参数传递到Thread类的构造器中,创建Thread类的对象;
  5. 通过Thread类的对象调用start()
public class MRunnable implements Runnable {
   
    @Override
    public void run() {
   
        for(int i=1;i<=100;i++)
            if(i % 2 == 0)
                System.out.println(Thread.currentThread().getName()+":"+i);
    }
    
    public static void main(String[] args){
   
        MRunnable mRunnable = new MRunnable();
        Thread thread1 = new Thread(mRunnable);
        thread1.setName("线程1");
        Thread thread2 = new Thread(mRunnable);
        thread2.setName("线程2");
        thread1.start();
        thread2.start();
    }
}
三个窗口卖票2
/**
*	跟卖票1不一样的是,这里的ticket票数没有使用static,
*	因为上面是new了3个对象,所以有3个ticket
*	但这里是只new了一个对象,给了3个线程用
**/
public class 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值