赵雅智_java 多线程(3)之线程间的通信
线程间的通信
两个或两个以上的线程处理同一个资源,处理的动作是不一样的。
这样就需要将不同的动作代码放到不同的run方法中,run方法要封装到单独的类中。
使用方法:
同步中使用object类的方法
wait():让当前线程处于等待状态,释放cpu资源,同时释放锁。
notify():唤醒等待的线程,唤醒第一个
notifyAll():唤醒所以等待的线程。
实例,生产者和消费者。
分析:
生产者-消费者问题是多线程同步处理的典型问题
有一块生产者和消费者共享的有界缓冲区,生产者往缓冲区放入产品,消费者从缓冲区取走产品这个过程可以无休止的执行,不能因缓冲区满生产者放不进产品而终止,也不能因缓冲区空消费者无产品可取而终止。
1.搭架子
package com.csdn;public class ProAndSell {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stub}}//资源类class Resource{String name;String sex;}//生产类class Product implements Runnable{@Overridepublic void run() {// TODO Auto-generated method stub}}//销售类 class Sell implements Runnable{@Overridepublic void run() {// TODO Auto-generated method stub}}2.填充代码
package com.csdn;public class ProAndSell {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubResource r = new Resource();Product pro = new Product(r);Sell se = new Sell(r);Thread t1 = new Thread(pro);Thread t2 = new Thread(se);t1.start();t2.start();}}//资源类class Resource{String name;String sex;}//生产类class Product implements Runnable{private Resource r;public Product(Resource r){this.r = r;}@Overridepublic void run() {int x = 0;while(true){if(x == 0){r.name = "张三";r.sex = "男";} else {r.name = "lisi";r.sex = "nv";}x=(x+1)%2;}}}//销售类 class Sell implements Runnable{private Resource r;public Sell(Resource r){this.r = r;}@Overridepublic void run() {while(true){System.out.println(r.name+"...."+r.sex);}}}
两个线程,首先输入的线程生产出张三,男,CPU资源没有切换给输出线程,输入还拥有CPU资源,接着生产,生产张三,CPU资源切换给输出,出现张三.......nv
3.封锁,同步代码块
package com.csdn;public class ProAndSell {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubResource r = new Resource();Product pro = new Product(r);Sell se = new Sell(r);Thread t1 = new Thread(pro);Thread t2 = new Thread(se);t1.start();t2.start();}}//资源类class Resource{String name;String sex;}//生产类class Product implements Runnable{private Resource r;Object obj = new Object();public Product(Resource r){this.r = r;}@Overridepublic void run() {int x = 0;while(true){synchronized (obj) {if(x == 0){r.name = "张三";r.sex = "男";} else {r.name = "lisi";r.sex = "nv";}}x=(x+1)%2;}}}//销售类 class Sell implements Runnable{private Resource r;Object obj = new Object();public Sell(Resource r){this.r = r;}@Overridepublic void run() {while(true){synchronized (obj) {System.out.println(r.name+"...."+r.sex);}}}}
还是有错误,是以为上锁的时候是两把锁
4.让生产者和消费者有共同的锁
package com.csdn;public class ProAndSell {/** * @param args */public static void main(String[] args) {// TODO Auto-generated method stubResource r = new Resource();Product pro = new Product(r);Sell se = new Sell(r);Thread t1 = new Thread(pro);Thread t2 = new Thread(se);t1.start();t2.start();}}//资源类class Resource{String name;String sex;}//生产类class Product implements Runnable{private Resource r;public Product(Resource r){this.r = r;}@Overridepublic void run() {int x = 0;while(true){synchronized (r) {if(x == 0){r.name = "张三";r.sex = "男";} else {r.name = "lisi";r.sex = "nv";}}x=(x+1)%2;}}}//销售类 class Sell implements Runnable{private Resource r;public Sell(Resource r){this.r = r;}@Overridepublic void run() {while(true){synchronized (r) {System.out.println(r.name+"...."+r.sex);}}}}
线程的随机性
5.线程的通信
package com.csdn;public class ProAndSell {public static void main(String[] args) {// TODO Auto-generated method stubResource r = new Resource();Product pro = new Product(r);Sell se = new Sell(r);Thread t1 = new Thread(pro);Thread t2 = new Thread(se);t1.start();t2.start();}}//资源类class Resource{String name;String sex;boolean f;}//生产类class Product implements Runnable{private Resource r;public Product(Resource r){this.r = r;}@Overridepublic void run() {int x = 0;while(true){synchronized (r) {if(r.f)try {r.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}if(x == 0){r.name = "张三";r.sex = "男";} else {r.name = "lisi";r.sex = "nv";}r.f = true;r.notify();}x=(x+1)%2;}}}//销售类 class Sell implements Runnable{private Resource r;public Sell(Resource r){this.r = r;}@Overridepublic void run() {while(true){synchronized (r) {if(!r.f)try {r.wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(r.name+"...."+r.sex);r.f = false;r.notify();}}}}
6.优化代码
package com.csdn;public class ProAndSell {public static void main(String[] args) {// TODO Auto-generated method stubResource r = new Resource();Product pro = new Product(r);Sell se = new Sell(r);Thread t1 = new Thread(pro);Thread t2 = new Thread(se);t1.start();t2.start();}}//资源类class Resource{private String name;private String sex;private boolean f;public synchronized void set(String name, String sex){if(f)try {wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}this.name = name;this.sex = sex;f=true;notify();}public synchronized void out(){if(!f)try {wait();} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}System.out.println(name+"...."+sex);f = false;notify();}}//生产类class Product implements Runnable{private Resource r;public Product(Resource r){this.r = r;}@Overridepublic void run() {int x = 0;while(true){if(x == 0){r.set("张三", "男");} else {r.set("lisi", "nv");}x=(x+1)%2;}}}//销售类 class Sell implements Runnable{private Resource r;public Sell(Resource r){this.r = r;}@Overridepublic void run() {while(true){r.out();}}}
三段代码并行
package com.csdn;public class ThreadDemo6 {/** * @param args */public static void main(String[] args) {new Thread(){public void run(){for(int i=0;i<100;i++){System.out.println("a="+i);}}}.start();for(int i=0;i<100;i++){System.out.println("b="+i);}Runnable r=new Runnable(){@Overridepublic void run() {for(int i=0;i<100;i++){System.out.println("c="+i);}}};new Thread(r).start();}}