黑马程序员——Java多线程基础知识2
时间:2014-05-13 02:42:52
收藏:0
阅读:452
多线程协同 |
线程间的通讯:我们对资源的操作动作不同,比如说两个卡车一个拉煤一个装煤。但是他们共享了一个资源。
怎么样把这个资源拿出来?怎样把车装满?这个资源当然是一个类,他里面的组成元素就是对象!!现在我们就要有操作对象的思想了,我用对象把这车装满,现在一车装一个对象。
等待唤醒机制;
用的不是sleep是wait。flag标记,这是两人沟通的方式。其实每个标记就要做一次等待或者notify,判断wait,改值notify。线程池。notify唤醒里面的线程,按顺序唤醒。wait和notify必须用在同步上,r其实是监视器。必须标识锁。任意对象能调用的方法当然定义在object上。watinotify,notifyall因为要对持有监视器的线程操作,所以要使用同步中,因为只有同步才具有锁。只有容易锁上被等待的线程,才可以被唤醒。也就是说,等待和唤醒必须是同一个锁,
根本停不下来。。。判断是否等待必须在判断执行哪个代码前。
代码优化,把这段代码简化。非静态方法的同步锁匙this。。。静态才是类名.class。
原理:匿名对象,第二个把属于资源的操作,比如加料,输出,放在资源这个类上,车子负责调用就行了。
生产消费这例子。
生产粮食的同时,也在吃粮食,我把控制条件改成了粮食的安全库存。
交叉。。。因为t2醒的时候,没有看标志,因为他是在下面醒的
出现生产多个而消费一个,或者生产一个消费多次:if判断一次,而while循环是多次的
锁死了,全部等待notifyAll()
package Practice; import java.util.Random; class Stage { Random rand=new Random(); private int size; private int count; public void setSize(int size){this.size=size;} public void setCount(int count){this.count=count;} public int getSize(){return size;} public int getCount(){return count;} public String toString(){return "仓库大小:"+size+"\t剩余:"+count+"。";} public boolean flag=false; public synchronized void push() { while(flag) try{wait();} catch(Exception e){} int temp=rand.nextInt(size-count); System.out.println(toString()+Thread.currentThread().getName()+",准备生产:"+temp); count+=temp; flag=true; notifyAll(); } public synchronized void pop() { while(!flag) try{wait();} catch(Exception e){} int temp=rand.nextInt(count); System.out.println(toString()+Thread.currentThread().getName()+",准备消费:"+temp); count=count-temp; flag=false; notifyAll(); } } class Productor implements Runnable{ // TODO Auto-generated method stub private Stage s; Productor(Stage s){this.s=s;} public void run() { while(true) s.push(); } } class Consummer implements Runnable{ private Stage s; Consummer(Stage s){this.s=s;} public void run() { // TODO Auto-generated method stub while(true) s.pop(); } } public class MyThreadTest { public static void main(String[] args) { // TODO Auto-generated method stub ; Stage s=new Stage(); s.setSize(80); s.setCount(10); new Thread(new Productor(s) ).start(); new Thread(new Productor(s) ).start(); new Thread(new Consummer(s) ).start(); new Thread(new Consummer(s) ).start(); } }//打印结果 /*仓库大小:80 剩余:69。Thread-1,准备生产:2 仓库大小:80 剩余:71。Thread-2,准备消费:51 仓库大小:80 剩余:20。Thread-1,准备生产:47 仓库大小:80 剩余:67。Thread-3,准备消费:49 仓库大小:80 剩余:18。Thread-0,准备生产:16 仓库大小:80 剩余:34。Thread-3,准备消费:30 仓库大小:80 剩余:4。Thread-1,准备生产:31 仓库大小:80 剩余:35。Thread-2,准备消费:14 仓库大小:80 剩余:21。Thread-1,准备生产:26 仓库大小:80 剩余:47。Thread-3,准备消费:34 . . . */
多线程其他常见操作 |
jdk5.0升级版后换成了lock和condition。显式的锁和显示的唤醒机制,一个锁对应多个condition,不懂的看看api。其实就是Condition condition_pro=lock.condition();
Lock lock 为什么newreen。。(关键是要try和finally)(新建一个多重锁~)
怎么停止循环(线程)?原理只有一种,停止run,要开启多线程的通常都是循环结构,只要控制了循环就能结束。
强制做这件事情,如果调用冻结状态,结果被冻结了,强制清除冻结状态。interrupted。清除冻结状态。。。发生异常了,人家不该醒,你让人家醒了。怎么让程序结束呢?在catch里面加入改变flag的语句,强制让线程回到运行状态来,就可以操作标记让线程结束。
守护线程 程序怎么结束了?后台线程,当前台线程都结束时,后台线程会自动结束。当一个线程依赖另一个线程时,可以通过将线程标志成setdaemon;必须在线程启动前标3f记。
join
加入。join也是抛出异常。join的意思就是说,t1申请要cpu的执行权,住线程被冻结,t1结束了就能回来。等待t1执行完才能执行,临时加入线程,让这段线程执行完再执行。碰到谁的join就等谁死。当A线程执行到B线程的jion时,a就等待到b执行完。b要是wait呢?
toString:覆盖了obj的tostring。
优先级,线程组是个对象,把你new的线程对象放里面就行了。但是用的频率很低。优先级表示抢资源的能力,默认都是5.一共就10级,5和10 没啥区别。
yeile,暂停当前线程对象执行其他对象。会是多线程,一人执行一次。
开发的时候怎么写线程呢?
当某些代码需要同时被执行时,匿名内部类。。。独立运算不相干的时候
他们并不是协同的时候可以用,这个时候可以继承thread,另外runnable是不能创对象的,必须创thread指向runnable;
评论(0)