Thread知识

1.基础知识

1.sleep()的作用是在指定的毫秒数内让当前"正在执行的线程"休眠.
2.getId()获取线程的唯一标识
3.停止线程3种方法

- 使用退出标志,正常退出
- 使用stop强行终止线程,已废弃.(他会抛出一个ThreadDeath异常.不需要捕获)
- 使用interrupt中断线程,他不会立即停止线程,而是加一个停止的标记.(在线程中捕获这个标记.进行主动退出)
- 使用抛出异常.try-catch停止线程

4.静态方法 interrupted()返回当前正在运行的线程是否已经中断.,在哪个线程里调就返回哪个线程的中断状态
线程的方法 isInterrupted()返回调用线程是否已经中断,哪个线程对象调用他,他返回哪个线程的中断状态.
5.suspend()方法暂定线程 resume()方法恢复线程,缺点是会占有公共对象的锁和数据不同步
6.yield()使当前线程放弃当前的CPU资源,但放弃时间不确定,有可能刚放弃马上又获得CPU时间片.
7.线程优先级 1-10 , 10最高.优先级高得到的CPU资源较多.但不是绝对的.优先级具有继承性,如A线程启动B线程.则B线程的优先级和A相同.
8.守护线程,是特殊的线程.当进程中不存在非守护线程时,守护线程自动销毁. gc就是守护线程.
9.synchronized 关键字取得的就是对象锁.而一个对象只有一把锁.当一个线程获得一个对象的锁后.可以直接访问他所有的带锁的方法.称为锁的重入机制.可重入锁也支持父子类继承的环境中.既子类拿到对象锁后.可以访问父类的带锁的方法.
10.一个线程执行的代码出现异常时,其所持有的锁会自动释放.
11.锁不能被继承.既父类的同步方法加了锁.在子类重写后却没加锁,那么子类方法不会继承父类的锁.因为锁是针对对象的.创建子类对象时不会创建父类对象.也就不涉及父类对象的锁的方法.
12.同步代码快.可以减少同步等待的时间.不再同步代码块中的代码是异步执行,同步代码块中的代码同步执行.同步代码块也是锁定某个对象的.
13.synchronized关键字加到static方法上是给Class类上锁,而synchronized关键字加到非static静态方法上是给对象加锁.而String具有常量池.不建议对String 加锁.
14.volatile关键字.使变量在多个线程间可见.

1.png

  • volatile关键字强制从公共内存中读取变量的值.而不使用每个线程的工作内存.
  • volatile增加了实例变量在多个线程之间的可见性
  • volatile是线程同步的轻量级实现,效率比synchronized高并且volatile只能修饰变量
  • 多线程访问volatile不会发送阻塞,而访问synchronized会出现阻塞
  • volatile能保证数据的可见性,但不保证原子性(原子性:即一个操作或者多个操作 要么全部执行并且执行的过程不会被任何因素打断,要么就都不执行)而synchronized可保证原子性,继而保证可见性
  • volatile解决的是变量在多个线程的可见性,synchronized解决的是多个线程访问资源的同步性(个人理解volatile用来读值比较好.写的话会数据错乱,并不能保证同步性.)
    15.wait/notify方法在调用前线程必须持有对象锁,这两个方法属于object.wait调用后会释放锁.notify方法执行后,当前线程要把同步方法执行完才会释放锁.之后wait的线程被唤醒,拿到对象锁.如果某线程wait后没有其他线程调用notify.则这个线程会一直等待下去.即时对象锁已经被释放. notifyAll唤醒全部wait的线程.
    16 执行完同步代码块会释放锁.执行同步代码块过程中如果遇到异常终止,会释放锁.执行锁对象的wait方法会释放锁.notify方法一次会随机唤醒一个wait方法.
    17.通过管道进行线程间通信,可以通过字节流,字符流.
    pipeStream (管道流)用于在不同线程间直接发送数据,一个线程发送数据到管道,另一个线程从管道中读取数据.
    18.join的作用是等待线程对象销毁.Z线程中调用X.join使所属线程对象X正常执run()方法,而使当前线程Z进行无限期的阻塞,等待线程X销毁后在继续执行Z后面的代码.
    join在内部是使用wait方法实现,所以会释放锁.而sleep不会释放锁.
    join过程中调用interrupt会抛出异常.
    19.threadLocal可以为每个线程单独设置自己的值.inheritableThreadLocal可以让子线程从父线程中取得父线程继承下来的值.
    20.ReentrantLock类,用来实现同步功能,支持获得锁,释放锁.
lock.lock() 获得锁  lock.unlock() 释放锁
Condition 是在一个Lock对象里面创建多个Condition(对象监视器)实例,线程对象可以注册在指定的Condition中,从而可以有选择性的进行线程通知
在调度上更加灵活.既可以唤醒指定线程
Condition的wait,sign方法需要在Lock.lock后调用.
公平锁.线程获取锁的顺序是根据线程枷锁的顺序来分配的,非公平锁,线程获得锁是随机的.ReentrantLock构造函数可以传boolean表示公平锁还是非公平锁
getHoleCount()返回当前线程保持次锁定的个数,也就是调用lock方法的次数.
getQueueLength() 返回等待获取锁的线程的个数.
getWaitQueueLength(Condition condi) 返回等待condition的wait的线程数. 
tryLock() 仅在锁未被另一个线程保持时,才获取该锁.
awaitUntil(mills) 在等待mills的到期时间前可以被唤醒.不必非要等待mills长的时间

21.ReenTrantReadWriteLock读写锁
读写锁分为两个锁.读锁,称为共享锁. 写锁,称为排它锁.多个写锁或者多个读锁加写锁互斥.既可以多线程读.只能单线程写.
22.单例模式与多线程结合
1.恶汉模式,静态变量直接创建对象.然后返回
2.懒汉模式.在调用时返回.正规写法是双检查机制

1.png

3.私有的静态内部类创建外部类对象.提供方法返回外部类对象.

1.png

4.序列化|反序列化单例对象时,需要重写 readResolve方法返回单例对象
5.静态代码块创建单例对象.

1.png

6.枚举实现单例模式.(使用枚举类时,构造方法被自动调用,在枚举的构造方法中创建单例类的单例对象)
23.线程的状态
-new 至今尚未启动(创建后还没start)
-runnable 正在java虚拟机中执行(可能获得了CPU时间片,也可能没获得CPU时间片)
-blocked 受阻塞并等待某个锁

-waiting      无限期的等待另一个线程来执行某一特定操作
-timewaitting    在指定时间内等待另一线程执行某一特定操作
-terminated    已退出的线程
1.png

1.单例模式的写发

所有的单例模式都是构造函数私有化.成员以private static 修饰,提供公开static 方法访问.不让别人实例化他,

1.恶汉模式.就是加载类时候就加载,缺点是不能有其他实例变量,因为getInstance无法同步.
如果从始至终从未使用过这个实例,则会造成内存的浪费
  public class A{ 
    private static A obj =new A(); //直接实例化
     也可以使用静态代码块
    private static A obj;
    static {
      obj=new A();
    }
    private A(){}
    public static A getInstance(){
      return obj;
    }
  }

2.懒汉模式.调用时候加载,单线程的时候没事.多线程会产生多个obj对象.
 public class A{
    private static A obj;
    private A(){}
    public static A getInstance(){
      if(obj ==null){
        //初始化东西
        obj =new A();
      }
        return obj;
    }
  }
3.懒汉模式加 synchronized 关键字. 方法加锁.导致方法需要等待某线程执行完才释放锁.方法执行效率低.
public class A{
  private static A obj;
  private A(){}
  sychnorized public static A getInstance(){ 
      if(obj ==null){
      obj =new A();
      }
      return obj;
  }
}
4.另一种懒汉模式加锁.其实和3是一样的
public class A{
  private static A obj;
  private A(){}
  
  public static A getInstance(){
    synchronized(A.class){  //锁住类对象,同时代码块锁要在 obj判断外边.不然没意义.
         if(obj ==null){
            obj =new A();
         }
    }
    return obj;
   }
}
 5.懒汉模式加dcl(doublc check lock) 双检查锁机制
    public class A {
      private volatile static A obj;   volatile关键字使所有线程强制去主存储区拿obj变量.
      private A () {}
      public static A getInstance(){
        if(obj ==null){
              //这里可以进行一些线程无关的初始化,保证不需要同步的代码异步执行
              synchronized(A.class){   
                   if( obj ==null){ //这里判空是为如果有线程阻塞,先前进来的已经创建完毕,就不需要在创建了.
                      obj=new A();
                    }
              }
       }
        return  obj;
      }
    }
6.使用静态内部类, 不需要外部类的引用,效果同双检查锁
采用了类装载的机制来保证初始化实例时只有一个线程,
内部类是延时加载的,也就是说只会在第一次调用时加载。不调用就不加载
  public class A{
    private A(){}
    private static class B{
        private static A obj =new Object();
    }
    public static A getInstance{
        return B.obj;
    }
  }
7.枚举方式,在使用枚举时,构造方法被自动调用.不仅能避免多线程同步问题,而且还能防止反序列化重新创建新的对象,
每一个枚举类型和定义的枚举变量在JVM中都是唯一的
  public class B{
    public enum C{
       factory;  //枚举类型
       private A obj; //需要初始化的参数
        private C{  //枚举的构造函数会在调用枚举类型时候执行.
            obj =new A();
        }
        public  A getA(){
            return obl;
        }
    }
    public static A getInstance(){
      return B.factory.getA();
     }
  }
  8.单例模式在序列化时.重新读取会生成新的对象.解决方法如下
public class A {
  private staitc A obj =new A();
  protected A(){}

  /反序列时直接返回当前INSTANCE
   private Object readResolve() {     //重写这个方法.返回之前创建的
            return INSTANCE;     
      }    
}




最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,108评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,699评论 1 296
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,812评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,236评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,583评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,739评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,957评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,704评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,447评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,643评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,133评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,486评论 3 256
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,151评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,889评论 0 197
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,782评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,681评论 2 272

推荐阅读更多精彩内容

  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 3,637评论 0 11
  • 本文出自 Eddy Wiki ,转载请注明出处:http://eddy.wiki/interview-java.h...
    eddy_wiki阅读 1,906评论 0 14
  • 从没有这么想改变过。 排球比赛结束了,该回去了,期待了这么久的传校比赛没有让我失望,除了我,每一个打的都很好。...
    慜玭阅读 125评论 0 0
  • “ 在所有条件相同的情况下,最简单的解释往往是正确的。”(๑•ᴗ•๑)风里雨里,小妖陪你♡ Ellie Arrow...
    八尾小妖阅读 491评论 0 1
  • 贾瑞这么个胆小懦弱无能之人为什么会看上王熙凤这样厉害的角色呢? 我个人认为贾瑞之所以会看上凤姐有三个理由...
    婉㚥阅读 1,865评论 0 10