完成任务
1.线程结尾(毕向东第12天看完)
收获
多线程实现生产消费问题
- 对于两个线程使用if()notify()是可以的
- 但对于多个线程要使用while()notifyAll()
原因:让被唤醒的线程在进行一次判断标记
public synchronized void set(String name){ while(flag) try{this.wait();}catch(Exception e){} this.name = name+".."+count++; System.out.println(Thread.currentThread().getName()+"..."+"生产者"+this.name); flag = true; notifyAll(); }
- 为什么要使用notifyAll()
- 因为要唤醒对方线程
- 只用notify(),容易出现只唤醒本方线程的情况,导致所有线程都在等待
- JDK1.5 中提供了多线程升级解决方案
- 将同步synchronized替换成显示Lock操作
- 将Object中的wait(),notify(),notifyAll()
- 替换了Condition对象await(),signal(),signalAll()
- 该对象可以Lock锁进行获取
- 该实例中,实现了本方只唤醒对方操作
通过 一个锁可以创建多个condition实现
public class Resouce1 { private String name; private int count = 0 ; private boolean flag = false ; Lock lock = new ReentrantLock(); Condition condition_pro = lock.newCondition(); Condition condition_con = lock.newCondition(); public void set (String name)throws Exception{ lock.lock(); try{ while(flag) condition_pro.await(); this.name = name+"**"+count++; System.out.println(Thread.currentThread().getName()+"...生产者。。"+this.name); flag = true; condition_con.signal(); }finally{ lock.unlock(); }}
其他有意思的方法
stop方法已经过时
如何停止线程
- 只有一种,run方法结束
开启多线程运行,运行代码通常是循环结构
只要控制住循环,就可以让run方法结束,也就是线程结束
特殊情况:
- 当线程处于了冻结状态
就不会读取到标记,那么线程就不会结束
当没有指定的方式让冻结的 线程恢复到运行状态时,
- 这时需要对冻结进行清楚
- 强制让线程回复到运行状态中来,
这样就可以操作标记让线程结束
Thread 类提供了该方法 interrupt()
public class StopThreadDemo { public static void main (String [] args){ StopThread st = new StopThread(); Thread t1 = new Thread(st); Thread t2 = new Thread(st); //t1.setDaemon(true); //t2.setDaemon(true); t1.start(); t2.start(); int num = 0 ; while (true){ if(num ++ == 60){ //st.changeFlag(); t1.interrupt(); t2.interrupt(); break; } System.out.println(Thread.currentThread().getName()+".."+num); } } }
》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》》
public class StopThread implements Runnable{ private boolean flag = true; public synchronized void run (){ while(flag){ try{ wait(); }catch(InterruptedException e){ System.out.println(Thread.currentThread().getName()+"....Exception"); flag = false; } System.out.println(Thread.currentThread().getName()+".....run"); } } public void changeFlag(){ flag = false; } }
- 守护线程t1.setDaemon(true);
依赖于前台线程,如果前台线程结束守护线程自动结束
join()的特点
当a线程执行到了b线程的join方法是,a等待,等b都执行完,a才执行
join可以用来临时加入线程执行
优先级t1.setPriority(Thread.MAX_PRIORITY);
Thread.yield()
- 暂时释放执行权,略微减缓执行频率,达到线程接近平均执行