`
赵雅智
  • 浏览: 97334 次
  • 性别: Icon_minigender_2
  • 来自: 北京
社区版块
存档分类
最新评论

赵雅智_java 多线程(3)之线程间的通信

 
阅读更多

线程间的通信

两个或两个以上的线程处理同一个资源,处理的动作是不一样的。

这样就需要将不同的动作代码放到不同的run方法中,run方法要封装到单独的类中。

使用方法:

同步中使用object类的方法

wait():让当前线程处于等待状态,释放cpu资源,同时释放锁。
notify():唤醒等待的线程,唤醒第一个
notifyAll():唤醒所以等待的线程。

实例,生产者和消费者。

分析:

生产者-消费者问题是多线程同步处理的典型问题

有一块生产者和消费者共享的有界缓冲区,生产者往缓冲区放入产品,消费者从缓冲区取走产品
这个过程可以无休止的执行,不能因缓冲区满生产者放不进产品而终止,也不能因缓冲区空消费者无产品可取而终止。

  1. 线程B写一次,线程A读一次
  2. 在某个时候线程B运行速度比较快,在线程A未读取上一个数据之前,B就写了第二次数据,造成数据遗漏。
  3. 在某个时候线程A运行速度比较快,它读完一次数据之后,线程B还没来得及写,线程A又来读第二次。结果线程A读不到数据,导致运行出错。
  4. 线程B正在写数据时,线程A也来读取数据,这时可能线程B还没将数据写完,线程A将数据读走,导致程序出错。

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{

	@Override
	public void run() {
		// TODO Auto-generated method stub		
	}
}

//销售类 
class Sell implements Runnable{

	@Override
	public 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 stub
		Resource 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;
	}
	@Override
	public 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;
	}
	@Override
	public 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 stub
		Resource 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;
	}
	@Override
	public 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;
	}
	@Override
	public 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 stub
		Resource 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;
	}
	@Override
	public 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;
	}
	@Override
	public 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 stub
		Resource 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;
	}
	@Override
	public void run() {
		int x = 0;
		
		while(true){
			synchronized (r) {
				if(r.f)
					try {
						r.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.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;
	}
	@Override
	public void run() {
		
		while(true){
			
			synchronized (r) {
				if(!r.f)
					try {
						r.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.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 stub
		Resource 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 block
				e.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 block
				e.printStackTrace();
			}
		System.out.println(name+"...."+sex);
		f = false;
		notify();
	}
	
}

//生产类
class Product implements Runnable{
	private Resource r;
	public Product(Resource r){
		this.r = r;
	}
	@Override
	public 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;
	}
	@Override
	public 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(){

			@Override
			public void run() {
				for(int i=0;i<100;i++){
					System.out.println("c="+i);
				}
			}			
		};
		new Thread(r).start();
	}
}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics