• ##什么是线程?


    在我们开始今天的线程之前,我们先来几道干货,是什么呢?就是我们一般取公司面试可能会被问道的面试题:

      1,描述java中多线程运行原理,

      2,会用继承方式的会创建多线程,

      3,会用实现接口的方式的会创建多线程

      4,能够说出线程6个状态的名称,

      5,能够解决线程安全问题(同步代码块 锁)

    一。多线程

    1.1并发与并行:

      并发:两个或者两个以上的事件,同一段时间内发生

      并行:两个或者两个以上的事件,同一时刻发生

    1.2进程与线程:

      进程:一个内存中运行的应用程序

      线程:进程中一个执行单元  复制当前进程中程序的执行  一个进程中至少有一个线程  一个进程是可以有多个线程的    这个程序可以称为多线程程序

    线程调度 :   jvm采用是抢式调度  没有分时调度

    1.3主线程:

      其实我们从刚接触Java的时候,就已经开始接触主线程了,对的,那就是我们的main方法

      作为程序的入口,它也作为我们程序运行的主线程存在

    1.4创建线程类  Thread类  

      概述: java. lang .Thread类代表线程 所有的线程对象都必须是Thread类或者它的子类 

    如何使用的步骤:

      1,集成Thread类  并重写run方法

      2,创建Thread子类的实例就是创建了线程对象

      3,调用线程对象的方法start()启动线程 

    public class MyThread extends Thread{
        @Override
        public void run() {
            System.out.println(Thread.currentThread().getName());
        }
    }

    1.5  Thread类  重点

      getName();  获取线程的名字

      start();    启动线程

      run();    重写run'方法

      sleep();    休眠

      currenThread();  返回对当前正在执行的线程对象的引用

    public class Test {
        public static void main(String[] args) {
            MyThread mt = new MyThread();
            mt.start();
            new MyThread().start();
            new MyThread().start();
            System.out.println(Thread.currentThread().getName());
        }
    }

    1.6实现接口方式  重难点

      创建线程的另一种方法就是声明实现Runnable接口的类,该类然后实现run方法  

      在用接口的时候我们一般要去先实现这个接口

    创建多种线程的步骤:

        1,创建实现Runnable

        2,重写run方法

        3,创建Runnable接口类的对象

        4,创建Thread类对象  构造方法里面传递Runnable接口里面的实现对象

        5,调用Thread类中的start方法  开启新的线程  执行run方法

    那么在这里相信很多人都会这样的疑惑:我们为啥要用实现的方法区创建多线程呢?

    1,一个类如果集成了Thread类,不能集成其他类

    2,一个类实现了Runnable接口还可以区集成其他类

    public class Demo01Runnable {
        public static void main(String[] args) {
           //3创建Runnnable接口实现类的对象
             RunnableImpl ruirui = new RunnableImpl();
    //     4  创建Thread类对象   构造方法中传递Runnable接口中的实现类对象
            Thread t = new Thread(ruirui);
    //      5 调用Thread类中start  方法  开启新的线程   执行run方法
            t.start();
            //主线程开启
            for(int i= 0;i<20;i++){
                System.out.println(Thread.currentThread().getName()+"--->"+i);
            }
        }
    }

    二。线程安全

    当我们使用多个线程访问同一个资源 ,并且多个线程中对资源有写的操作 就容易出现线程安全问题 解决  java中提供同步来解决   synchronized 

    那么相对的会有三种解决方法:

      1,同步代码块

      2,同方法

      3,Lock锁

    就拿我们买票的现实生活案例来说,一个窗口买票属于单线程,那么多个窗口卖票是不是就是多线程呢?

    先看下我们如何区实现:

    首先我们会创建一个类:

    public class RunnableImpl implements  Runnable{
        // 定义共享资源   线程不安全
        private int ticket = 100;
        // 线程任务  卖票
        @Override
        public void run() {
            while(true){
                if(ticket>0){
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    //卖票操作
                    System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
                    ticket--;
                }
            }
    
        }
    }

      然后创建线程:

    public class Demo01PayTicket {
        public static void main(String[] args) {
            RunnableImpl r  = new RunnableImpl();
            // 创建3个线程
            Thread t = new Thread(r);
            Thread t1 = new Thread(r);
            Thread t2= new Thread(r);
            t.start();
            t1.start();
            t2.start();
        }
    }

      这里我们以三线程为例

    可是卖票容易出现一个问题,可能这个窗口卖的票,其他窗口也买,那么出现这个问题我们怎么解决?

      二。1同步代码块的方法

    它的步骤分为三步:

      1,建立锁对象  任意对象

      2,必须保证多个线程使用的是同一个锁对象

      3,把{}只让一个线程进

    public class RunnableImpl implements  Runnable{
        // 定义共享资源   线程不安全
        private int ticket = 100;
        //在成员位置创建一个锁对象
        Object obj = new Object();
        // 线程任务  卖票
        @Override
        public void run() {
            while(true){
                //建立锁对象
                synchronized (obj){
                    if(ticket>0){
                        try {
                            Thread.sleep(100);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        //卖票操作
                        System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
                        ticket--;
                    }
                }
    
            }
    
        }
    }

    二。2同方法:

    它的步骤是:

      1,创建一个方法  修饰符添加synchronized

      2,把访问了共享数据的代码放进方法中

      3,调用同步方法

    public class RunnableImpl implements  Runnable{
        // 定义共享资源   线程不安全
        private int ticket = 100;
        // 线程任务  卖票
        @Override
        public void run() {
            while(true){
                payTicket();
            }
        }
        public synchronized void payTicket(){
    
            if(ticket>0){
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                //卖票操作
                System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
                ticket--;
            }
        }
    }

    二。3Lock锁

    它的步骤是:

    1,在成员位置 创建Lock接口的实现类 ReentrantLock

    2,在可能会出现代码的问题前面 调用lock方法

    3,在可能会出现代码的问题后面,调用unlock方法 释放锁对象

    public class RunnableImpl implements  Runnable{
        // 定义共享资源   线程不安全
        private int ticket = 100;
        // 线程任务  卖票
    //    1   在成员的位置  创建Lock接口的实现类 ReentrantLock
        Lock l = new ReentrantLock();
    
        @Override
        public void run() {
            while(true){
                // 2  在可能会出现代码的问题前面  调用lock 方法
                l.lock();
                if(ticket>0){
                    try {
                        Thread.sleep(100);
                        //卖票操作
                        System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
                        ticket--;
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }finally {
                        //3   在可能会出现代码的问题后面  调用unlock()   释放锁对象
                        l.unlock();
                    }
    
                }
            }
    
        }
    }

     三。线程状态

    概述:当线程被创建后,不是--启动就进入执行状态

      1,New线程刚被创建 但是未被启动

      2,Runnable可运行JVM里的状态

      3,Blocked阻塞

      4,waiting无线等待一个线程在等待另外一个线程唤醒

      5,TimeWaiting计时等待

      6,Teminated被终止因为run()正常退出而死亡

  • 相关阅读:
    python--模块
    python--*args与**kw
    python--偏函数
    Reversible Cards ARC111 -B 思维,图论
    Simple Math ARC111
    状压DP详解(位运算)
    E
    Ball CodeForces
    Reward HDU
    Choosing Capital for Treeland CodeForces
  • 原文地址:https://www.cnblogs.com/liurui-bk517/p/10932487.html
Copyright © 2020-2023  润新知