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;
    }
  • 相关阅读:
    HDU 4611 Balls Rearrangement 数学
    Educational Codeforces Round 11 D. Number of Parallelograms 暴力
    Knockout.Js官网学习(简介)
    Entity Framework 关系约束配置
    Entity Framework Fluent API
    Entity Framework DataAnnotations
    Entity Framework 系统约定配置
    Entity Framework 自动生成CodeFirst代码
    Entity Framework CodeFirst数据迁移
    Entity Framework CodeFirst尝试
  • 原文地址:https://www.cnblogs.com/tongxuping/p/6832242.html
Copyright © 2011-2022 走看看