一:
- 线程间的通讯:其实就是多个线程在操作同一资源,但是操作的动作不同
- 第一步:考虑同步
二:
第二步:共享的代码都需要同步
第三步:同步代码快(里面对象的选择)
三:
- 等待唤醒机制:
- Wait()和 notify() notifyAll()的时候必须在try catch包起来 ,都使用在同步中,因为要对监视器(锁)的线程操作,所以要使用在同步中,因为只有同步才具有锁
另外,这些线程的方法都必须定义在object类中, 因为这些方法在操作同步中线程,可以被同一个锁上的notify唤醒。不可以对不同锁中的线程进行唤醒。
也就是说:等待和唤醒必须是同一个锁
而锁可以是任意的对象,所以可以被任意对象调用的方法定义在object类中
四:
- 为什么定义 notifyAll()
因为需要唤醒对方线程,因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待
- JDK1.5中提供了多线程的升级解决方案
- JDK1.5之后 Condition将Object监视器方法(wait,notify,notifyALL)分解成截然不同的对象,Condiition对象可以Lock锁进行获取,以便将这些对象与任意的Lock实现组合使用,为每个对象提供多个等待set(wait-set),其中,lock替代了synchronized方法和语句的使用,Condition替代了Object监视器方法的使用(注意try catch 的使用 释放锁的一定要执行)一个锁上面可以有多个condition
在该实例中,实现了本方只唤醒对方操作--------使用与生产者和消费者的例子
五:
- 如何停止线程
只有一种,run方法结束,开启多线程运行,运行代码通常都是循环结构,只要控制住循环,就可以让run方法结束,也就是线程结束
- 当线程处于冻结状态,就不会读取到标记,那么线程就不会结束
- setDaemon(true)守护线程,该方法必须在启动线程之前调用。当正在运行的线程是守护线程时,Java虚拟机退出
- join()申请CPU的执行权:当A线程执行到B线程的join()方法时,A就会等待。等B线程执行完,A才会执行
- .getPriority()设置线程的优先级。标准优先级就是默认的优先级是5,优先级的范围是[1,10],优先级越高不代表一直被CPU执行,是执行的次数比较多
- .yield()暂停当前的线程,执行其他的线程
多线程典型例子:
package sxy; public class ThreadTest { /** * @param args */ public static void main(String[] args) { // TODO Auto-generated method stub new Thread(){ public void run(){ for(int x=0;x<100;x++){ System.out.println(Thread.currentThread().getName()+"..1.."+x); } } }.start(); for(int x=0;x<100;x++){ System.out.println(Thread.currentThread().getName()+"..2.."+x); } Runnable r = new Runnable(){ public void run(){ for(int x=0;x<100;x++){ System.out.println(Thread.currentThread().getName()+"..3.."+x); } } }; new Thread(r).start(); } }