day12线程间的通信,等待唤醒机制,生产者消费者问题。新锁lock(): 守护线程,interrupt()停止线程用,join()yield()

/*
线程间的通信,等待唤醒机制,生产者消费者问题。新锁lock(): 守护线程,interrupt()停止线程用,join()yield()
*/


/*线程间通信:
	其实就是多个线程在操作同一个资源。
	但是操作的动作不同。
	思考1:wait(),notify(),natifyAll()用来操作线程为什么定义在Object类中?
	1.这些方法存在于同步中
	2.使用这些方法时必须要标识所属的同步的锁
	3.锁可以是任意对象。所以任意对象调用的方法一定定义在object类中
	思考2.wait(),sleep()的区别?
	wait():释放资源,释放锁
	sleep()释放资源,不释放锁。
*/
	class Res
	{
		String name;
		String sex;
		boolean flag = false;
	}

	class Input implements Runnable
	{
		private Res s = null;
		 Input(Res s)
		{
			this.s = s;
		}
		public void run()
		{
			int x = 0;
			
				while (true)
				{
					synchronized(s)//同步安全的二个前提,二个线程,同一个锁。
					{
						if(s.flag)
							try{s.wait();}catch(Exception e){}
						if (x==1)
						{
							s.name = "mike";
							s.sex = "man";
							//system.out.println(s.name+s.Res);
						}
						else
						{
							s.name = "丽丽";
							s.sex = "女女女女女女女";
						}
						x=(x+1)%2;
						s.flag = true;
						s.notify();
					}
				}
			
		}
	}

	class Output implements Runnable
	{
		private Res s = null;
		Output(Res s)
		{
			this.s = s;
		}
		public void run()
		{
			
			while (true)
			{
				synchronized(s){
					if(!s.flag)
						try{s.wait();}catch(Exception e){}
					System.out.println(s.name+s.sex);
					s.flag = false;
					s.notify();

				}
			}
		}
	}

	class InOutDemo
	{
		public static void main(String[] args)
		{
			Res s = new Res();
			new Thread(new Input(s)).start();
			new Thread(new Output(s)).start();
		}
	}
	/*等待唤醒机制:
		wait(),notify();
		必须持有同一把锁。
	
	
	*/


生产者消费者问题:

class ProducerConsumerDemo 
{
	public static void main(String[] args) 
	{
		ResSoure r = new ResSoure();
		Thread t1 = new Thread(new Producer(r));
		Thread t2 = new Thread(new Consumer(r));
		t1.start();
		t2.start();
		//加上t3,t4
	}
}

class ResSoure
{
	private String name;
	private boolean flag = false;
	private int count = 1;

	public synchronized void set(String name)
	{
		while(flag)//不用if,用了while,多个生产线程时会出现全部等待。
			try{wait();}catch(Exception e){}
		this.name = name+"..."+count++;
		System.out.println(Thread.currentThread().getName()+"--生产者--"+this.name);
		flag = true;
		notifyAll();
	}

	public  synchronized void out()
	{
		while (!flag)
			try{wait();}catch(Exception e){}
		System.out.println(Thread.currentThread().getName()+"--消费者--"+this.name);
		flag = false;
		notifyAll();
	}
}

class Producer implements Runnable
{
	private ResSoure r;
	Producer(ResSoure r)
	{
		this.r = r;
	}
	public void run()
	{
		while(true)
		{
			r.set("生产者");
		}
	}
}

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


 

JDK1.5升级版  新锁
	lock(): 获取锁  unlock():释放锁.
	synchronized :释放锁是隐式过程。lock是显式的。
	
	private Lock lock = new ReentrantLock();
	private Condition condition = lock.newCondition();//可以多个
	condition.await();condition.signal();
import java.util.concurrent.locks.*;
class LockDemo
{
	public static void main(String[] args) 
	{
		ResSoure r = new ResSoure();
		Thread t1 = new Thread(new Producer(r));
		Thread t2 = new Thread(new Consumer(r));
		Thread t3 = new Thread(new Producer(r));
		Thread t4 = new Thread(new Consumer(r));
		t1.start();
		t2.start();
		t3.start();
		t4.start();
		//加上t3,t4
	}
}

class ResSoure
{
	private String name;
	private boolean flag = false;
	private int count = 1;
	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)//不用if,用了while,多个生产线程时会出现全部等待。
					condition_pro.await();
				this.name = name+"..."+count++;
				System.out.println(Thread.currentThread().getName()+"--生产者-----"+this.name);
				flag = true;
				condition_con.signal();
			}
		
			finally{
			lock.unlock();
			}
		
	}

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

			
			
	}
}

class Producer implements Runnable
{
	private ResSoure r;
	Producer(ResSoure r)
	{
		this.r = r;
	}
	public void run()
	{
		while(true)
		{
			try
			{
				r.set("生产者");
			}
			catch (Exception e)
			{
			}
			
		}
	}
}

class Consumer implements Runnable
{
	private ResSoure r;
	Consumer(ResSoure r)
	{
		this.r = r;
	}
	public void run()
	{
		while(true)
		{
			try
			{
				r.out();
			}
			catch (Exception e)
			{
			}
			
		}
	}
}

停止线程

 stop方法已经过时,不再推荐使用。强制停止,这是不OK的。

 那么如何停止线程?
 只有一种,run方法结束。

 开启多线程运行,运行代码通常都是循环结构。
 只要控制住循环,就可以让run方法结束,也就是线程结束。

 特殊情况:
 当线程处于冻结状态
 就不会读取到标记,那么线程不会结束。

 当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结进行清除。
 强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束。


 中断方法:interrupt(),Thread类中的方法,
 该方法是结束线程的冻结状态,使线程强制回到运行状态来。只有运行,才能读取标记。

 当线程处于wait(),sleep()时,可以用interrupt()使线程醒过来,读取结束标记。



 

import java.util.*;

class Reser implements Runnable
{
	private int num = 0;
	 boolean flag = true;
	public synchronized void run()
	{
		while (flag)
		{
			try
			{
				wait();//线程1,2都挂在这了。因为wait()会释放锁
			}
			catch (InterruptedException e)
			{
				System.out.println("...Exception...");
				flag = false;//更换条件,让线程结束。
			}
			System.out.println(Thread.currentThread().getName()+"......"+num++);
		}
		
	}
}

class  Interrupt
{
	public static void main(String[] args)
	{
		 int count = 0;
		Reser rr = new Reser();
		t1.setDaemon(true);//true标记守护线程,启动前标记。
		t2.setDaemon(true);
		Thread t1 = new Thread(rr);
		Thread t2 = new Thread(rr);
		t1.start();t2.start();

		while (true)
		{
			if ((count++) == 60)
			{
				//rr.flag = false;
				//t1.interrupt();//唤醒,让t1回到运行状态,去运行。
				//t2.interrupt();
				break;
			}
			System.out.println(Thread.currentThread().getName() +"----"+ count);
		}
	}
	
}


 

守护线程:后台线程。开启后,和前台线程都抢CPU,
	当所有前台线程都结束后,后台线程自动结束。
	setDaemon()
	public final void setDaemon(boolean on)

	参数:
	on - 如果为 true,则将该线程标记为守护线程。 
	抛出: 
	IllegalThreadStateException - 如果该线程处于活动状态。 
	SecurityException - 如果当前线程无法修改该线程。


	将该线程标记为守护线程或用户线程。当正在运行的线程都是守护线程时,Java 虚拟机退出。 
	该方法必须在启动线程前调用。 

	设置1.2二个守护线程,当主线程结束后,没有设置flag为false;线程一样结束。

	---------------
	join()方法:如果满足条件,临时加入进来。当线程遇到 join,就等谁执行完。
	特点,当A线程执行到B线程的join方法时,a就会等待,等B执行完。
	join可以用来临时加入线程执行。


	toString() 

		返回该线程的字符串表示形式,包括线程名称、优先级和线程组。

		setPriority(int newPriority)更改线程的优先级。

		设置优先级,0到10。数字越大,优先级越高。

		1.5.10最明显。

		MAX_PRIORITY 
			   线程可以具有的最高优先级。

			   使用方法。t1.setPriority(Thread.MAX_PRIORITY)

		 MIN_PRIORITY 
				 线程可以具有的最低优先级

		NORM_PRIORITY 
				 分配给线程的默认优先级。


	yield()暂停当前正在执行的线程对象,并执行其他线程。
	Thread.yield();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值