Java面向对象 线程技术 -- 下篇



Java面向对象 线程技术 -- 下篇

知识概要:

             (1)线程间的通信           生产者 - 消费者

             (2)生产者消费者案例优化

             (3)守护线程

             (4)停止线程

             (5)join

             (6)yield与优先级


线程间的通信      生产者 - 消费者

线程间通讯:
           其实就是多个线程在操作同一个资源,但是操作的动作不同。

代码示例

class Res
{
	private String name;
	private String sex;
	private boolean flag = false;

	public synchronized void set(String name,String sex)
	{
		if(flag)
			try{this.wait();}catch(Exception e){}
		this.name = name;
		
		this.sex = sex;
		flag = true;
		this.notify();
	}
	public synchronized void out()
	{
		if(!flag)
			try{this.wait();}catch(Exception e){}
		System.out.println(name+"........"+sex);
		flag = false;
		this.notify();
	}
}

class Input implements Runnable
{
	private Res r ;
	Input(Res r)
	{
		this.r = r;
	}
	public void run()
	{
		int x = 0;
		while(true)
		{
			if(x==0)				
				r.set("mike","man");				
			else	
				r.set("丽丽","女女女女女");				
			x = (x+1)%2;
		}
	}
}

class Output implements Runnable
{
	private Res r ;
	
	Output(Res r)
	{
		this.r = r;
	}
	public void run()
	{
		while(true)
		{
			r.out();
		}
	}
}


class  InputOutputDemo2
{
	public static void main(String[] args) 
	{
		Res r = new Res();

		new Thread(new Input(r)).start();
		new Thread(new Output(r)).start();
		/*
		Input in = new Input(r);
		Output out = new Output(r);

		Thread t1 = new Thread(in);
		Thread t2 = new Thread(out);

		t1.start();
		t2.start();
		*/
	}
}


生产者消费者案例优化

         生产者和消费者共同对同一份资源进行处理,其实质上就是线程的通信。如何更好的处理好线程之间的通信?

import java.util.concurrent.locks.*;

class ProducerConsumerDemo2 
{
	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(pro);
		Thread t3 = new Thread(con);
		Thread t4 = new Thread(con);

		t1.start();
		t2.start();
		t3.start();
		t4.start();

	}
}

/*
JDK1.5 中提供了多线程升级解决方案。
将同步Synchronized替换成现实Lock操作。
将Object中的wait,notify notifyAll,替换了Condition对象。
该对象可以Lock锁 进行获取。
该示例中,实现了本方只唤醒对方操作。

Lock:替代了Synchronized
	lock 
	unlock
	newCondition()

Condition:替代了Object wait notify notifyAll
	await();
	signal();
	signalAll();
*/
class Resource
{
	private String name;
	private int count = 1;
	private boolean flag = false;
			//  t1    t2
	private Lock lock = new ReentrantLock();

	private Condition condition_pro = lock.newCondition();
	private Condition condition_con = lock.newCondition();



	public  void set(String name)throws InterruptedException
	{
		lock.lock();
		try
		{
			while(flag)
				condition_pro.await();//t1,t2
			this.name = name+"--"+count++;

			System.out.println(Thread.currentThread().getName()+"...生产者.."+this.name);
			flag = true;
			condition_con.signal();
		}
		finally
		{
			lock.unlock();//释放锁的动作一定要执行。
		}
	}


	//  t3   t4  
	public  void out()throws InterruptedException
	{
		lock.lock();
		try
		{
			while(!flag)
				condition_con.await();
			System.out.println(Thread.currentThread().getName()+"...消费者........."+this.name);
			flag = false;
			condition_pro.signal();
		}
		finally
		{
			lock.unlock();
		}
		
	}
}

class Producer implements Runnable
{
	private Resource res;

	Producer(Resource res)
	{
		this.res = res;
	}
	public void run()
	{
		while(true)
		{
			try
			{
				res.set("+商品+");
			}
			catch (InterruptedException e)
			{
			}
			
		}
	}
}

class Consumer implements Runnable
{
	private Resource res;

	Consumer(Resource res)
	{
		this.res = res;
	}
	public void run()
	{
		while(true)
		{
			try
			{
				res.out();
			}
			catch (InterruptedException e)
			{
			}
		}
	}
}

停止线程

       stop方法已经过时。

      如何停止线程?
      只有一种,run方法结束。
      开启多线程运行,运行代码通常是循环结构。

      只要控制住循环,就可以让run方法结束,也就是线程结束。


   特殊情况:

   当线程处于了冻结状态。
   就不会读取到标记。那么线程就不会结束。

   当没有指定的方式让冻结的线程恢复到运行状态是,这时需要对冻结进行清除。 

    强制让线程恢复到运行状态中来。这样就可以操作标记让线程结束。

    Thread类提供该方法 interrupt();


class StopThread implements Runnable
{
	private boolean flag =true;
	public  void run()
	{
		while(flag)
		{
			
			System.out.println(Thread.currentThread().getName()+"....run");
		}
	}
	public void changeFlag()
	{
		flag = false;
	}
}




class  StopThreadDemo
{
	public static void main(String[] args) 
	{
		StopThread st = new StopThread();
		
		Thread t1 = new Thread(st);
		Thread t2 = new Thread(st);


		t1.setDaemon(true);
		t2.setDaemon(true);
		t1.start();
		t2.start();

		int num = 0;

		while(true)
		{
			if(num++ == 60)
			{
				//st.changeFlag();
				//t1.interrupt();
				//t2.interrupt();
				break;
			}
			System.out.println(Thread.currentThread().getName()+"......."+num);
		}
		System.out.println("over");
	}
}

守护线程

那Java的守护线程是什么样子的呢。

当JVM中所有的线程都是守护线程的时候,JVM就可以退出了;

如果还有一个或以上的非守护线程则不会退出。    
    
所以setDeamon(true)的唯一意义就是告诉JVM不需要等待这个线程运行结束(退出),当JVM想退出的时候就可以退出吧



join


当A线程执行到了B线程的.join()方法时,A就会等待。等B线程都执行完,A才会执行。

join可以用来临时加入线程执行。

yield:个人理解,就是暂时释放线程,这样线程的执行权就会落到别的线程上。

代码示例

class Demo implements Runnable
{
	public void run()
	{
		for(int x=0; x<70; x++)
		{
			System.out.println(Thread.currentThread().toString()+"....."+x);
			Thread.yield();
		}
	}
}


class  JoinDemo
{
	public static void main(String[] args) throws Exception
	{
		Demo d = new Demo();
		Thread t1 = new Thread(d);
		Thread t2 = new Thread(d);
		t1.start();
		
		t1.setPriority(Thread.MAX_PRIORITY);

		t2.start();

		t1.join();

		for(int x=0; x<80; x++)
		{
			System.out.println("main....."+x);
		}
		System.out.println("over");
	}
}





posted @ 2014-05-30 15:19  博客园杀手  阅读(175)  评论(0)    收藏  举报