好久没看线程的东西了,今天没啥事,回顾一下最最基本的一些知识点。

1:程序、进程、线程的区别?

程序:保存在物理介质中的代码片段
进程:运行中的程序,也就是说一个程序 跑起来之后就变成了操作系统中的一个进程
线程:程序当中一条独立的执行线索

2:线程的五大状态?

        新生(Born)      就绪(Runnable)     运行(Running)     消亡(Dead)
           阻塞(Blocking )

3:创建线程的方式?每种方式的特点?

1:extends Thred   覆盖run方法
2:implements Runnable   覆盖run方法
3:implements Callable<T>  @Override  public T call() throws Exception{}
 *:call()不再是void方法,所以线程结束以后可以返回数据
 *:call()定义的时候throws Exception 所以可以在县线程体重抛出异常

4:如何控制线程?

0.setPriority(int) 设置线程优先级别 可选范围1-10 默认5

        *:优先级高的会更多次的得到时间片

           但是绝对无法保证先执行或者先执行完

 

1.static sleep(long)   让当前线程休眠指定的毫秒数

        *:从运行转往阻塞状态 待指定的毫秒数后返回就绪

 

2.static yield()   让当前线程直接返回就绪状态

        *:根本无法保证当前线程一定不先执行~

 

3.join()       涉及到两个线程

               一个线程邀请另一个线程优先执行

               在被邀请的线程执行结束之前

               邀请别人的线程不再执行 一直阻塞~

*:线程章节中的所有静态方法,都只能操作当前处于运行状态的线程,所以我们需要关注的是方法写在哪,而不是谁调用了。

*:线程中所有涉及到主动进入阻塞的方法(sleep / join)都需要进行异常处理,因为它们都throws InterruptedException

5:线程的一些常用方法?

setName() +getName() : 设置和得到线程的名字

        *: 没有枪 没有炮 我们还能自己造

 

static activeCount() : 得到程序当中活跃线程的总数~

        *: 活跃 = 就绪 + 运行 + 阻塞

        *: 这个方法永远不可能返回0~

   

static currentThread() : 得到正在运行状态的线程对象~

        *: 这个方法永远不可能出现在run()当中

           因为那将完全等价于this

           可能出现在两个场景:

           1.主方法当中用来得到主线程对象~

           2.run()当中调用的其它方法当中 搞清是哪个线程调用的~

 

setDaemon(true) : 将调用方法的线程设置为守护线程

        *: 守护线程 - 为其它线程提供服务的线程

           当程序当中只有守护线程的时候守护线程自行结束~

 

interrupt() : 中断 打断线程的阻塞状态~

        *: sleep(long) 或者 join() 都会导致当前线程阻塞

           但是 我们能反悔吗?


6:锁

互斥锁 => 互斥锁标记 => 锁标记 => 锁旗标=> 监视器 => monitor

 

  1st way:

    synchronized => 修饰符 => 同步的

        修饰代码块:

           synchronized(临界资源){

               需要连续执行的操作1;

               需要连续执行的操作2;

               需要连续执行的操作3;

           }

 

        修饰方法:

           public synchronized void add(Objectobj){

               ...;

           }

           等价于 从方法第一行到方法最后一行统统加锁

           对当前对象this进行加锁~

           stu.add()  set.add() list.add()

           *:如果synchronized修饰静态方法 则相当于对

               整个类进行加锁(理解为对.class文件加锁)

 

        *:方法的synchronized特性 不会被继承~ 只能去覆盖

        *:StringBuffer + Vector + Hashtable=> synchronized

        *:单例模式的懒汉式需要synchronized修饰~

 

  2nd way:

    java.util.concurrent.locks.ReentrantLock

        lock()     锁

        unlock()   释放锁

        *:效率更高 功能更强大 更符合OO思想

           但是 对程序员要求较高...

 

互斥锁标记使用过多或者使用不当 就会出现线程相互等待对方释放资源

    而又不释放自己的资源给其它线程使用的永久阻塞情况~

 

如何解决死锁

    0.顺序的摆放锁标记的位置 [别想了 这需要改变程序逻辑]

    1.线程间相互"通讯"   [相互谦让 相互成全彼此]

        wait():    当前线程放弃已经持有的锁标记和时间片

               直接进入调用方法的对象的"等待池"当中

 

        notify():  从调用方法的那个对象的等待池当中

               随机的唤醒一个线程  

 

        notifyAll():   从调用方法的那个对象的等待池当中

               唤醒所有等待的线程

 

        *:这三个方法都是Object类的方法 所以Java当中每个对象都会

        *:这三个方法都必须在已经持有锁标记的情况下使用 =>

           所以它们一定会出现在synchronized(xxx){}

           否则 程序会出现运行时异常~

   

    锁池和等待池 请问它们有什么相同点和不同点?

    进入的时候 是否需要释放资源

        锁池不需要释放 才会形成死锁的!

        等待池需要释放

 

    出来的时候 是否需要调用代码

        锁池不需要

        等待池必须要其它线程唤醒(notify() or notifyAll())

 

    出来之后去到哪

        锁池回到就绪

        等待池直奔锁池!

    ----------------------------------------------------

已知:Vector类的add() remove() 全是synchronized修饰的

    有一个Vector对象叫v

    有两个线程对象 t1 和 t2

   

请问:当t1线程调用v对象的add() 方法开始执行了但是还没执行完成的时候

    t2线程能不能调用v对象的add();    不能

    t2线程能不能调用v对象的remove();     不能

 

 

已知:Vector类的add() remove() 全是synchronized修饰的

    有两个Vector对象叫v1 和 v2

    有两个线程对象 t1 和 t2

 

请问:当t1线程调用v1对象的add() 方法开始执行了但是还没执行完成的时候

    t2线程能不能调用v1对象的add();       不能

    t2线程能不能调用v1对象的remove();    不能

    t2线程能不能调用v2对象的add();       能

    t2线程能不能调用v2对象的remove();    能


7:java中的volatile关键字