线程(java)

程序、线程、进程!!!

程序程序(program)是为完成特定任务、用某种语言编写的一组指令的集合。即指一

段静态的代码。

线程:进程((process)就是正在执行的程序,从Windows角度讲,进程是操作系统进行

资源分配的最小单位。

进程线程(thread)进程可进一步细化为线程,是一个进程内部的最小执行单元,是操

作系统进行任务调度的最小单元,隶属于进程。
作为小白,我们是不是会?

  

 看完以上漫画,我觉得大家已经有一定的认识了,接下来让我们走入线程世界

       单核CPU:顾名思义,就是只能执行一个线程,只能一件事做完才能做下一件事,CPU利用率极低!

多核CPU:

 多核CPU:就是可以同时进行多个线程,CPU的利用率较高

注意:多线程同时运作并不是真正的同时运行,而是一件一件的来做,但是每个线程之间切换的时间非常快,在我们日常生活中,我们是不是经常在吃饭的时候看手机呢?我们是不是认为我们看手机和吃饭时同时进行的呢?实则不然,(除非你可以左手画圆,右手画正方形),其实我们一瞬间在看手机,下一瞬间就在吃饭,俩件事情时间间隔短,所以我们被我们的大脑所欺骗,多线程也是这个原理!!!


线程和进程的关系

一个进程可以包含多个线程,一个线程只能属于一个进程,线程不能脱离进程而独立运行;

每一个进程至少包含一个线程(称为主线程);在主线程中开始执行程序,java 程序的入口main()方法就是在主线程中被执行的。

在主线程中可以创建并启动其它的线程;

一个进程内的所有线程共享该进程的内存资源。

如何创建一个线程:

  • Thread
public class MyThread extends Thread {//Thread需要被继承,

    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println("ThraedB"+i);
        }
    }
public class Demo1 {
    public static void main(String[] args) {
        System.out.println("线程开始");
        MyThread thread=new MyThread();
        thread.start();
        for (int i = 0; i < 1000; i++) {
            System.out.println("ThraedA"+i);
        }
        System.out.println("线程结束");
    }
}
  • Runnable
public class Demo2 implements Runnable{
    @Override
    public void run() {
        for (int i = 0; i < 1000; i++) {
            System.out.println(Thread.currentThread().getName()+":"+i);
        }
    }
}
public class Demo3 {
    public static void main(String[] args) {
        System.out.println("线程开始");
        Demo2 demo=new Demo2();
       Thread thread=new Thread(demo);
        thread.start();
        Demo2 demo1=new Demo2();
        Thread thread1=new Thread(demo);
        thread1.start();

        System.out.println("线程结束");
    }
}
继承方式和实现方式的联系与区别 (区别)
  • 继承Thread: 线程代码存放Thread子类run方法中。
  • 实现Runnable:线程代码存在接口的子类的run方法。
实现Runnable的好处
  • 避免了单继承的局限性。
  • 多个线程可以共享同一个接口实现类的对象,非常适合多个相同线程来处理同一份资源。

 Thread类中方法

  • void start()         启动线程
  • final String getName()               返回线程的名称
  • final void setPriority(int newPriority)                设置线程的优先级
  • final int getPriority()                                  返回线程的优先级
  • final void join()                  等待线程终止
  • static Thread currentThread()            返回对当前正在执行的线程对象的引用
  • static void sleep(long millis)             让当前正在执行的线程休眠(暂停执行),休眠时间由milli s(毫秒)指定
  • yield()           线程让步
 public void run() {
        for (int i = 0; i <1000 ; i++) {
            System.out.println(Thread.currentThread().getName()+"."+i);//获取线程的名字
//            try {
//                Thread.sleep(10000);//让线程休眠(指定**ms)
//            } catch (InterruptedException e) {
//                e.printStackTrace();
//            }
//            if(i%10==0){
//                Thread.yield();//线程让步,主动让出CPU执行权
//            }
public static void main(String[] args) {
        System.out.println("线程开始");
        Happy happy = new Happy();
        Thread thread = new Thread(happy);
        thread.start();
//        thread.setPriority(9);//设置优先级,[1,10]
//        System.out.println(thread.getPriority());
//        try {
//            thread.join();//等待这个线程死亡
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        Happy happy1 = new Happy();
        Thread thread1 = new Thread(happy1);
        thread1.start();
//        thread.setPriority(5);
//        System.out.println(thread1.getPriority());
        System.out.println("线程结束");
        for (int i = 0; i < 1000; i++) {
            System.out.println(Thread.currentThread().getName() + "." + i);
        }
    }

线程优先级:

  • 事实上,计算机只有一个CPU,各个线程轮流获得CPU的使用权,才能执行任务;
  • 优先级较高的线程有更多获得CPU的机会,反之亦然;
  • 优先级用整数表示,取值范围是1~10,一般情况下,线程的默认优先级都是5,但是也可以通过setPriority和getPriority方法来设置或返回优先级;

 调度策略:

  • 时间片
  • 抢占式:高优先级的线程抢占CPU

 调度方法:

同优先级线程组成先进先出队列,使用时间片策略

对高优先级,使用优先调度的抢占式策略

线程状态:线程和我们生命一样,在某个时刻有某个状态。

新建--就绪--等待(阻塞)--运行--死亡

  • 新建:当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态
  • 就绪处于新建状态的线程被start()后,将进入线程队列等待CPU时 间片,此时它已具备了运行的条件,只是没分配到CPU资源
  • 运行当就绪的线程被调度并获得CPU资源时,便进入运行状态,run ()方法定义了线程的操作和功能
  • 阻塞在某种特殊情况下,被人为挂起或执行输入输出操作时,让出 CPU并临时中止自己的执行,进入阻塞状态
  • 死亡线程完成了它的全部工作或线程被提前强制性地中止或出现异常导致结束

 java中的线程分为俩类,一种是用户线程,一种是守护线程,任何一个守护线程都是整个JVM中所有非守护线程的保姆,只要当前JVM实例中尚存在 任何一个非守护线程没有结束,守护线程就全部工作;只有当最后一个非守护线程结束时,守护线程随着JVM一同结束工作。守护线程的作用是为其他线程的运行提供便利服务,守护线程最典型的应用就是 GC (垃圾回收器),它就是一个很称职的守护者。

多线程:

 

多线程:一个应用程序内部,可以同时执行多个任务;

多线程的优点:

1.提高程序处理能力,响应速度提高

2.提高CPU利用率,压榨硬件的价值,提高程序结构

缺点:1.线程也是程序,所以线程需要占用内存,线程越多,占用内存越多

2.多线程需要协调与管理(共享资源进行访问)

线程同步:

并行:多个CPU同时执行几多个任务

并发:在一个时间段内依次执行操作(多个事情依次执行)

解决方法:在多个线程依次进行的时候,为了不使线程运行混乱,java采用了排队+锁的方法,保证了安全,但是效率低。

  • synchronized
  • ReentranLock

 synchronized:修饰非静态方法,锁对象是this,修饰静态方法时锁对象是当前的class文件,每一个类被加载到内存中,为此类创建一个对应的class类的对象,用来表示获取类的信息,一个类对应一个class文件,是隐式锁,自动添加锁,同步代码块执行完毕或者出现问题(异常),锁会自动释放。

ReentranLock:是依靠java代码实现控制,只能修饰代码块,手动添加,手动释放。

线程死锁:多个线程分别占用的需要资源不放弃,等待对方释放资源,设计程序时需要考虑清楚顺序。

线程通信:多个线程相互牵制、相互调度,线程之间的相互作用

public class Demo1 extends Thread{
    Object objA=new Object();
    Object objB=new Object();
    boolean flag;

    public Demo1(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        if(flag){
        synchronized (objA){//上锁
            System.out.println("objA");
            synchronized (objB){//锁中锁
                System.out.println("objB");
            }
        }
        }else{
            synchronized (objB){//上锁
                System.out.println("objB");
                synchronized (objA){//锁中锁
                    System.out.println("objA");
                }
            }
        }

    }
}
public static void main(String[] args) {
        Demo1 demo1=new Demo1(true);
        Demo1 demo2=new Demo1(false);
        Thread t1=new Thread(demo1,"路飞");
        Thread t2=new Thread(demo2,"白胡子");
        t1.start();
        t2.start();
    }

wait : 阻塞、监听、锁对象来调

notify:  唤醒、等待的线程

notifyAll:同步代码块执行,锁会释放,唤醒所有等待的线程

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

吃橘子的Crow

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

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

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

打赏作者

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

抵扣说明:

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

余额充值