1.多线程-线程间通信-问题演示
多线程间通信:多个线程处理同一资源,但是处理动作却不同。
//创建一个资源描述。资源中有name sex。用于存储数据。 class Resource{ String name; String sex; } //需要定义一个输入任务描述。既然是线程任务,必须实现Runnable接口。 class Input implements Runnable{ private Resource r; Input(Resource r){ this.r = r; } //覆盖run方法。 public void run(){ int x = 0; while(true){ //输入任务中必然要处理资源。要给资源中的name sex赋值。 //需要对象。对象确定吗?不确定,传递进来就哦了。输入任务一创建对象就必须有资源。 //完全可以在构造时明确资源对象。 if(x==0){ r.name = "zhangsan"; r.sex = "man"; }else{ r.name = "小花"; r.sex = "女女女女女"; } //赋值后,将标记改为true,说明有值。 x = (x+1)%2; } } } //需要定义一个输出任务描述。既然是线程任务,必须实现Runnable接口。 class Output implements Runnable{ private Resource r; Output(Resource r){ this.r = r; } public void run(){ while(true){ System.out.println(r.name+"...."+r.sex); } } }
class ThreadDemo_Resource{ public static void main(String[] args) { //1,创建资源的对象。 Resource r = new Resource(); //2,创建任务对象。 Input in = new Input(r); Output out = new Output(r); //3,创建线程对象。 Thread t1 = new Thread(in); Thread t2 = new Thread(out); //4,启动并运行线程。 t1.start(); t2.start(); } }
运行结果:
2.多线程-线程间通信-问题解决
使用同步代码块
class Resource{ String name; String sex; } class Input implements Runnable{ private Resource r; Input(Resource r){ this.r = r; } public void run(){ int x = 0; while(true){ synchronized(r){ if(x==0){ r.name = "zhangsan"; r.sex = "man"; }else{ r.name = "小花"; r.sex = "女女女女女"; } } x = (x+1)%2; } } } class Output implements Runnable{ private Resource r; Output(Resource r){ this.r = r; } public void run(){ while(true){ synchronized(r){ System.out.println(r.name+"...."+r.sex); } } } }
class ThreadDemo_Resource{ public static void main(String[] args) { //1,创建资源的对象。 Resource r = new Resource(); //2,创建任务对象。 Input in = new Input(r); Output out = new Output(r); //3,创建线程对象。 Thread t1 = new Thread(in); Thread t2 = new Thread(out); //4,启动并运行线程。 t1.start(); t2.start(); } }
3.多线程-线程间通信-等待唤醒机制
wait():可以让当前处于等待,这时的线程被临时存储到的线程池中。
notify():唤醒线程池中任意一个等待的线程。
notifyAll():唤醒线程池中所有的等待线程。
这些方法在使用时,必须要定义在同步中,必须被所属同步的锁对象来调用。
//创建一个资源描述。资源中有name sex。用于存储数据。 class Resource{ String name; String sex; //定义标记,用于判断资源中是否有数据。 boolean flag;//默认值为false } //需要定义一个输入任务描述。 class Input implements Runnable{ private Resource r; Input(Resource r){ this.r = r; } public void run(){ int x = 0; while(true){ synchronized(r){ if(r.flag){//flag为false不执行wait语句 try{r.wait();}catch(Exception e){}} if(x==0){ r.name = "zhangsan"; r.sex = "man"; }else{ r.name = "小花"; r.sex = "女女女女女"; } //赋值后,将标记改为true,说明有值啦。 r.flag = true; //唤醒等待的线程。 r.notify(); } x = (x+1)%2; } } } //需要定义一个输出任务描述。 class Output implements Runnable{ private Resource r; Output(Resource r){ this.r = r; } public void run(){ while(true){ synchronized(r){ if(!r.flag){//资源中没有数据就等待。 try{r.wait();}catch(Exception e){}} System.out.println(r.name+"...."+r.sex); //将标记改为false. r.flag = false; r.notify();//唤醒等待的线程。其实就是唤醒了输入线程。 } } } } class ThreadDemo_Resource{ public static void main(String[] args) { //1,创建资源的对象。 Resource r = new Resource(); //2,创建任务对象。 Input in = new Input(r); Output out = new Output(r); //3,创建线程对象。 Thread t1 = new Thread(in); Thread t2 = new Thread(out); //4,启动并运行线程。 t1.start(); t2.start(); } }
运行结果
4.多线程-线程间通信-代码优化
//资源描述 class Resource{ private String name; private String sex; //定义标记,用于判断资源中是否有数据。 private boolean flag; //对外提供方法访问这些属性。 public synchronized void set(String name,String sex){ if(flag)//flag为false,输入任务不等待 try{this.wait();}catch(Exception e){} this.name = name; this.sex = sex; flag = true; this.notify(); } //对外提供获取方法。 public synchronized void out(){ if(!flag)//falg为false,输出任务等待 try{this.wait();}catch(Exception e){} System.out.println(name+"::::"+sex); flag = false; this.notify(); } } //需要定义一个输入任务描述。 class Input implements Runnable{ private Resource r; Input(Resource r){ this.r = r; } //覆盖run方法。 public void run(){ int x = 0; while(true){ if(x==0){ r.set("zhangsan","man"); }else{ r.set("小花","女女女女女"); } x = (x+1)%2; } } } //需要定义一个输出任务描述。 class Output implements Runnable{ private Resource r; Output(Resource r){ this.r = r; } public void run(){ while(true){ r.out(); } } } class ThreadDemo2_Resource{ public static void main(String[] args) { //1,创建资源的对象。 Resource r = new Resource(); //2,创建任务对象。 Input in = new Input(r); Output out = new Output(r); //3,创建线程对象。 Thread t1 = new Thread(in); Thread t2 = new Thread(out); //4,启动并运行线程。 t1.start(); t2.start(); } }
5.多线程-线程间通信-单生产者单消费者示例
/* 单生产者和单消费者。等待唤醒机制。 */ //资源 class Resource{ private String name;//定义一个商品都有名字。 private int count = 1;//定义一个商品的编号。 private boolean flag = false;//定义用来判断是否有商品的标记。 public synchronized void set(String name){ if(flag)//flag为false,生成任务不等待 try{wait();}catch(Exception e){} this.name = name+"--"+count; count++; System.out.println(Thread.currentThread().getName()+"---生产了,"+this.name); flag = true;//将标记改为true。 notify();//唤醒等待的线程。 } public synchronized void get(){ if(!flag)//flag为false,消费任务等待 try{wait();}catch(Exception e){} System.out.println(Thread.currentThread().getName()+"-------消费了....."+this.name); flag = false; notify(); } } //定义生产者的任务。 class Producer implements Runnable{ private Resource r; Producer(Resource r){ this.r = r; } public void run(){ while(true){ r.set("蛋糕"); } } } //定义消费者的任务。 class Consumer implements Runnable{ private Resource r; Consumer(Resource r){ this.r = r; } public void run(){ while(true){ r.get(); } } } class ThreadDemo_Producer_Consumer { public static void main(String[] args) { Resource r = new Resource(); Producer pro = new Producer(r); Consumer con = new Consumer(r); Thread t1 = new Thread(pro); Thread t2 = new Thread(con); t1.start(); t2.start(); } }
单生产单消费,等待和唤醒的始终只有一个线程,没有问题。
时间: 2024-11-06 12:53:59