/** * 多线程之间的通信 * * 1.什么是线程通信呢? * 就是多个线程操做同一个资源,但任务不一样 * * * 2.打个不恰当的比喻 : * 以药品的买卖为列子 * 一我的负责卖药品 * 一我的负责进口药品 * * 请问? * 这个是否是说,2我的在操做同一个资源“药品呢”?是的 * 可是他们两我的负责的任务倒是不同的 * * 一个任务是卖药品 * 一个任务是进口药品 * * 这个就叫线程之间的通信 * * 3.线程安全的问题? * 涉及到多线程,无论你是作什么的,一概都会存在线程安全的问题 * 这里牵扯一个CPU的问题 * * 3.1 CPU的执行资格 * 什么是CPU执行资格 * 说白了吧 过于底层不说,没意思 * 打个比喻 * 我如今建立 A B C D 4个任务,开启线程了 * 那么如今这个4个任务就具有了CPU执行资格并加入了执行队列中 * * 简单来讲执行资格为,我具有了被CPU处理的执行 * 3.2CPU的执行权 * 说白了, ABCD个任务, 好比 当前CPU对 A正在处理 * 那么A就有CPU的执行权 * * 简单点说执行权,我正在被CPU处理 * * 这个多线程啊,事实上并非,多个线程同时运行, * 其实就CPU在多个任务(也就线程嘛)之间快速的来回切换 * * (来回切换啊)那就会涉及一个问题 * CPU正在处理A任务,还没处理完,CP U忽然就切换到B处去处理B了 * 这就是所谓的线程安全问题? * * 解决方式为,同步锁 java 有个前提是,多个线程必须共享的同一个资源 * -- 同步函数 --同步代码块 * 其实PHP虽然不支持多线程 * 可是也会碰到相似的问题 * 那就在高并发的时候处理一个 任务,也会出现的问题, * 解决方式其实原理与java中同步锁是一个原理,咱们叫文件锁 * * 说白了吧,就是同一时刻只能有一个线程在操做我,其余的不行 * * **/ //药品资源 class DrugResource { String DrugName; /*药品名字*/ String Drugtype; /*西药or中药*/ } /**进口药品****/ class ImportDrugs implements Runnable { DrugResource d;//药品资源对象,保证,两个任务操做同一个对象 ImportDrugs(DrugResource d){ this.d = d; } public void run() { imports(); } public void imports() { int x = 0 ; while(true) { synchronized(d){ //同步锁也是同步代码块 前提是公用一个对象 d就是一个公用对象 if(x==0) //来回切换这个if--sele 取模运算给我线程没啥关系只是让他来显示看见的效果比较好 { d.DrugName = "penicillin -青霉素"; d.Drugtype = "penicillin -西药="; } else { // d.DrugName = "云南白药"; //d.Drugtype = "中药"; } x = (x+1)%2; //解释 x = (x+1)%2; /** * x =0时候 * (0+1)%2 * 1%2 = 1 * * x=1; * (1+1)%2 = 2%2 = 0 * * 这样就能切换了 * 这个东西没意义,可是仍是解释一下 */ } } } } /**卖药品****/ class SellDrugs implements Runnable { DrugResource d ; //药品资源对象,保证,两个任务操做同一个对象 SellDrugs(DrugResource d){ this.d = d; } public void run() { /**线程入口程序*/ sell(); } public void sell(){ while(true) { synchronized(d){ //Thread.currentThread().getName() 取出当前运行中进程名 System.out.println(Thread.currentThread().getName()+"卖出了.."+d.DrugName+"--品种--"+d.Drugtype); } } } } class TreadResource { public static void main(String[] args) { DrugResource d = new DrugResource(); //资源对象 ImportDrugs work1 = new ImportDrugs(d) ; //任务对象一 进口任务 SellDrugs work2 = new SellDrugs(d) ; //任务对象二 卖任务 /*********执行路径********/ Thread t1 = new Thread(work1); Thread t2 = new Thread(work2); t1.start(); //开启线程 t2.start(); //开启线程 } }