zoukankan      html  css  js  c++  java
  • java线程基本知识

    如何去定义一个线程?(三种方式)
        1.Thread:继承这个类,然后重写run方法;将业务逻辑或任务写到run方法中,然后调用start来启动线程;
        2.Runnable: 实现这个接口,然后重写run方法,创建Thread对象将Runnable实现类对象作为参数传递,最后调用start启动线程;
        3.Callable<T>:实现这个接口,然后重写Call方法;


    ---扩展---
        面试问题:Runnable和Callable有什么不同?
            包;
            泛型;
            方法;
            启动方式;
            执行完成之后Runnable结束,Callable没有结束;

    多线程并发问题:由于线程之间是有相互抢占资源导致程序出现不符合常理的问题

    锁:通过synchonized来锁定一段代码,需要一个对象,锁对象要求是所有的线程都得认识:共享资源、类的字节码

    wait()---让当前执行的线程等待,直到被唤醒才会继续执行
    notify()---唤醒在等待的线程
    通过wait/notify/notifyAll方法来调节线程之间的运行顺序---线程间的相互通信---等待唤醒机制
    当调用wait方法的时候,线程会去线程池中等待。而线程池本质上是一个存储线程的队列


    ---扩展---
    面试题总结:wait和sleep有什么区别?
    sleep方法需要指定一个沉睡时间,到点自然醒,释放执行权,不释放锁,是一个静态方法,被设计在了Thread类上
    wait方法可以指定时间也可以不指定,需要通过notify来唤醒。释放执行权,释放了锁,是一个普通的方法,被设计在了Object类上

    线程的基本状态:

    所有状态:

    1,创建状态

      在程序中用构造方法创建了一个线程对象后,新的线程对象便处于新建状态,此时,它已经有了相应的

    内存空间和其他资源,但还处于不可运行状态。新建一个线程对象可采用Thread 类的构造方法来实现,例

    如,“Thread thread=new Thread();”。

    2,就绪状态

      新建线程对象后,调用该线程的start()方法就可以启动线程。当线程启动时,线程进入就绪状态。此时,

    线程将进入线程队列排队,等待CPU 服务,这表明它已经具备了运行条件。

    3,运行状态

      当就绪状态的线程被调用并获得处理器资源时,线程就进入了运行状态。此时,自动调用该线程对象

    的run()方法。run()方法定义了该线程的操作和功能。

    4,堵塞状态

      一个正在执行的线程在某些特殊情况下,如被人为挂起或需要执行耗时的输入/输出操作时,将让出

    CPU 并暂时中止自己的执行,进入堵塞状态。堵塞时,线程不能进入排队队列,只有当引起堵塞的原因被

    消除后,线程才可以转入就绪状态。

    5,死亡状态

      线程调用stop()方法时或run()方法执行结束后,即处于死亡状态。处于死亡状态的线程不具有继续运

    行的能力。

    线程代码练习:

    public class synchronizedDemo {
        public static void main(String[] args) {
            syns s = new syns();
            synDemo syn = new synDemo(s);
            synDemo2 syn2 = new synDemo2(s);
            new Thread(syn).start();
            new Thread(syn).start();
            new Thread(syn2).start();
            new Thread(syn2).start();
            //new Thread(syn).start();
        }
    }
    class synDemo implements Runnable{
        private syns s;
        public synDemo(syns s) {
            this.s = s;
        }
        @Override
        public void run() {
            synchronized(s){
    //            try {
    //                Thread.sleep(3000);
    //            } catch (InterruptedException e) {
    //                e.printStackTrace();
    //            }
    //            try {
    //                s.wait();
    //            } catch (InterruptedException e) {
    //                e.printStackTrace();
    //            }
                for (int i = 0; i < 3; i++) {
                    String name = Thread.currentThread().getName();
                    System.out.println(name+":"+i);
                }
                //s.notify();
            }
            
        }
        
    }
    class synDemo2 implements Runnable{
        private syns s;
        public synDemo2(syns s) {
            this.s = s;
        }
        @Override
        public void run() {
            synchronized (s) {
    //            try {
    //                Thread.sleep(3000);
    //            } catch (InterruptedException e) {
    //                e.printStackTrace();
    //            }
                for (int i = 0; i < 3; i++) {
                    String name = Thread.currentThread().getName();
                    System.out.println(name+":"+i);
                }
            }
        }
    }
    class syns {
        private int a = 8;
    }
  • 相关阅读:
    675 对象的引用-浅拷贝-深拷贝
    674 vue3侦听器watch
    673 vue计算属性:缓存,setter和getter
    明明有了promise,为啥还需要async await?
    Js常用数组方法汇总
    一些非常有用的Js单行代码
    Js获取验证码倒计时
    前端截取字符串:JS截取字符串之substring、substr和slice详解
    javascript全局变量与局部变量
    JS实现快速排序算法
  • 原文地址:https://www.cnblogs.com/tongxuping/p/6832242.html
Copyright © 2011-2022 走看看