黑马程序员——Java基础知识之多线程协同

多线程协同
线程间的通讯:对资源的操作动作不同,比如说两个卡车一个拉煤一个装煤,但是他们共享了一个资源。
怎么样把这个资源拿出来?怎样把车装满?这个资源当然是一个类,他里面的组成元素就是对象!!现在我们就要有操作对象的思想了,用对象把这车装满,现在一车装一个对象。
等待唤醒机制;
用的不是sleep是wait。flag标记,这是两人沟通的方式。其实每个标记就要做一次等待或者notify,判断wait,改值notify。线程池。notify唤醒里面的线程,按顺序唤醒。wait和notify必须用在同步上,r其实是监视器。必须标识锁。任意对象能调用的方法当然定义在object上。watinotify,notifyall因为要对持有监视器的线程操作,所以要使用同步中,因为只有同步才具有锁。只有容易锁上被等待的线程,才可以被唤醒。也就是说,等待和唤醒必须是同一个锁,
代码优化,把这段代码简化。非静态方法的同步锁匙this。。。。静态才是类名.class
原理:匿名对象,第二个把属于资源的操作,比如加料,输出,放在资源这个类上,车子负责调用就行了。
生产消费这例子
生产粮食的同时,也在吃粮食,是个经典的协作多线程
import java. util. Random;
//仓库部分,是生产者和消费者的共享资源
class Stage
{
          Random randnew 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( sizecount );
                    System . out. println( toString ()+ ThreadcurrentThread() .getName ()",准备生产:" +temp );
                    count+= temp;
                    flagtrue;
                   notifyAll ();
           }
           public synchronized void pop ()
           {
                    while (! flag)
                              try {wait ()}
                    catch (Exception e ){}
                    int temp= rand. nextInt( count );
                    System . out. println( toString ()+ ThreadcurrentThread() .getName ()",准备消费:" +temp );
                    countcounttemp;
                    flagfalse;
                   notifyAll ();
           }
           }
//生产者部分
class Productor implements Runnable {
                    // TODO Auto-generated method stub
           private Stage s ;
          Productor ( Stage s){ thisss}
           public void run () {
                    while (true )
                              spush ();  
           }
           }
//消费者部分
           class Consummer implements Runnable {
                    private Stage s ;
                   Consummer ( Stage s){ thisss}
                    public void run () {
                              // TODO Auto-generated method stub
                              while (true )
                                       spop ();  
                    }
          
}
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升级版后换成了lockcondition。显式的锁和显示的唤醒机制,一个锁对应多个condition,不懂的看看api。其实就是Condition condition_pro=lock.condition();
Lock lock  为什么newreen。。(关键是要try和finally)(新建一个多重锁~)
怎么停止循环(线程)?原理只有一种,停止run,要开启多线程的通常都是循环结构,只要控制了循环就能结束。
强制做这件事情,如果调用冻结状态,结果被冻结了,强制清除冻结状态。interrupt//。清除冻结状态。。。发生异常了,人家不该醒,你让人家醒了。怎么让程序结束呢?在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;

黑马程序员——Java基础知识之多线程协同,布布扣,bubuko.com

黑马程序员——Java基础知识之多线程协同

上一篇:黑马程序员——Java多线程


下一篇:javascript中创建对象的几种方式