`
zhongsw
  • 浏览: 23545 次
文章分类
社区版块
存档分类
最新评论

黑马程序员_Java多线程知识点.

阅读更多

---------------------- android培训java培训 、期待与您交流! ----------------------

 

 

 

 

进程 : 是一个正在执行中的程序 . 每一个进程执行都有一个顺序 . 该顺序是一个路径 , 或者叫一个控制单元 .

线程 : 就是进程中的一个独立的控制单元 , 线程在控制着进程的执行 .

主线程执行 main 方法中的代码 , 自定义的线程执行 run 方法中的代码 .

Thread 类中的 run 方法 , 用于存储线程要运行的代码 .

xx.start();// 开启线程并执行线程中的 run 方法 .

xx.run();// 仅仅是对象调用方法 , 而线程在创建后并没有运行 .

 

创建线程的第一种方法 : 继承 Thread

1.       子类覆盖父类中的 run 方法 , 将线程运行的代码存放在 run .

2.       建立子类对象的同时线程也被创建 .

3.       通过调用 start 方法开启线程 .start 可以开启线程并同时调用 run 方法 .

 

第二种方式 : 实现 Runnable 接口 .

1.       定义类实现 Runnable 接口 .

2.       覆盖 Runnable 接口中的 run 方法 .

3.       通过 Thread 类建立线程对象 .

4.       Runnable 接口的子类对象作为实际参数传递给 Thread 类的构造函数 .

为什么要将 Runnable 接口的子类对象传递给 Thread 的构造函数 .?

因为自定义的 run 方法所属的对象是 Runnable 接口的子类对象 . 所以要让线程去指定指定对象的 run 方法 . 就必须明确该 run 方法所属对象 .

5.       调用 Thread 类的 start 方法开启线程并调用 Runnable 接口子类的 run 方法 .

 

线程由两种实现方式:

第一种方式:

class MyThread extends Thread{

   public void run(){

   需要进行执行的代码,如循环。

}

}

 

public class TestThread{

  main(){

   Thread t1=new Mythread();

   T1.start();

}

}

 

只有等到所有的线程全部结束之后,进程才退出。

 

第二种方式:

Class MyThread  implements Runnable{

  Public  void run(){

}

 

  MyThread target=new MyThread();

  Thread t3=new Thread(target);

  Thread.start();// 启动线程

 

实现方式和继承方式的区别 :

实现方式好处 : 避免了单继承的局限性 , 在定义线程时 , 建议使用实现方式 .

 

解决多线程运行的安全问题 , 用同步代码块 ( 需要锁 ). 也可以同步函数 .

synchronized( 对象 )

{

       需要被同步的代码

}

同步的前提 :

1.       必须要有两个或者两个以上的线程 .

2.       必须是多个线程使用同一个锁 .

 

必须保证同步中只有一个线程在运行 .

 

静态进内在时 , 内在中没有本类对象 , 但是一定有该类对应的字节码文件对象 . 类名 .class

静态的同步方法使用的锁是该方法所在类的字节码文件对象 .

单例设计模式懒汉式的同步 , 该同步所使用的锁是该类的字节码文件 .

 

多线程死锁的发生 . 简单举例二个线程互相要对方的锁能造成死锁 .

 

多线程 , 线程间的通讯

wait:

notify();

notifyAll();

都使用在同步中 , 因为要对持有监视器 ( ) 的线程操作 .

所以要使用在同步中 , 因为只有同步才具有锁 .

 

为什么这些操作线程的方法要定义在 object 类中呢 ?

因为这些方法在操作同步中线程时 , 都必须要标识它们所操作线程只有的锁 , 只有同一个锁上的被等待线程 , 可以被同一个锁上的 notify 唤醒 . 不可以对不同锁中的线程进行唤醒 .

也就是说等待和唤醒必须是同一个锁 .

而锁可以是任意对象 , 所以可以被任意对象调用的方法定义在 object .

 

Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。此实现允许更灵活的结构,可以具有差别很大的属性,可以支持多个相关的 Condition 对象。

 

JDK1.5 后的线程间通讯新特性

作为一个示例,假定有一个绑定的缓冲区,它支持 put take 方法。如果试图在空的缓冲区上执行 take 操作,则在某一个项变得可用之前,线程将一直阻塞;如果试图在满的缓冲区上执行 put 操作,则在有空间变得可用之前,线程将一直阻塞。我们喜欢在单独的等待 set 中保存 put 线程和 take 线程,这样就可以在缓冲区中的项或空间变得可用时利用最佳规划,一次只通知一个线程。可以使用两个 Condition 实例来做到这一点。

  class BoundedBuffer {

   final Lock lock = new ReentrantLock();

   final Condition notFull  = lock.newCondition();

   final Condition notEmpty = lock.newCondition();

 

   final Object[] items = new Object[100];

   int putptr, takeptr, count;

 

   public void put(Object x) throws InterruptedException {

     lock.lock();

     try {

       while (count == items.length)

         notFull.await();

       items[putptr] = x;

       if (++putptr == items.length) putptr = 0;

       ++count;

       notEmpty.signal();

     } finally {

       lock.unlock();

     }

   }

 

   public Object take() throws InterruptedException {

     lock.lock();

     try {

       while (count == 0)

         notEmpty.await();

        Object x = items[takeptr];

       if (++takeptr == items.length) takeptr = 0;

       --count;

       notFull.signal();

       return x;

     } finally {

       lock.unlock();

     }

   }

  }

 

多线程 , 停止线程 .

多线程运行的代码通常是循环结构 , 只要控制循环就可以让 run 方法结束 , 了就是线程结束 .

 

守护线程

  Join 方法 .   xx.setDaemon(true); 

优先级 Thread.yield(); 可以稍微减缓线程的运行 .

 

 

 

 

 

---------------------- android培训java培训 、期待与您交流! ----------------------

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics