---------------------- 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培训 、期待与您交流! ----------------------