黑马程序员--多线程(二)

------- android培训java培训、期待与您交流! ----------

1.线程通讯

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


注意:wait();notify();notifyAll()都使用在同步中,因为要对持有监视器的线程操作,所以要使用在同步中,因为只有同步才具有锁。


线程通讯实例

  /*
   生产鼠标,要求生产一个销售一个
  */
  class Mouse
  {
  	private String name;
  	private int count=1;
  	private boolean b = false;
  	Mouse(String name)//初始化对象
  	{
  	   this.name = name;
  	}
  
  	//定义产品类的生产功能,多过个线程去运行同一数据,需要同步
  	public synchronized void proc()
  	{
  	    while(this.b)//当为true时,表示鼠标生产出来了,还没卖出去,需要等待
  		  try
  		  {
  			this.wait();
  		  }
  		  catch (Exception e)
  		  {
  		  }
          System.out.println(name+"...生产了第...."+count+"个");
  		this.b = true;
  		this.notifyAll();//当生产出产品时,唤醒销售线程
  	}
  
  	public synchronized void cus()
  	{
  	    while(!this.b)
  			try
  			{
  				this.wait();
  			}
  			catch (Exception e)
  			{
  			}
  			System.out.println(name+"...消费了第"+count+"个");
  			count++;
  			this.b=false;
  			this.notifyAll();//销售后唤醒生产线程
  	}
  }
  //建立产品对象
  class Proc implements Runnable
  {
  	Mouse m = null;
  	Proc(Mouse m)
  	{
  	   this.m=m;
  	}
  	public void run()
  	{
  	    while(true)
  		{
  		   m.proc();
  		}
  	}
  }
  class Cus implements Runnable
  {
  	Mouse m = null;
  	Cus(Mouse m)
  	{
  	   this.m=m;
  	}
  	public void run()
  	{
  		while(true)
  		{
  		  m.cus();
  		}
  	}
  }
  class  ProcCusDemo
  {
  	public static void main(String[] args) 
  	{
  		Mouse m = new Mouse("鼠标");
  		Proc p = new Proc(m);
          Cus c = new Cus(m);
  		Thread t1 = new Thread(p);
  		Thread t2 = new Thread(c);
  		Thread t3 = new Thread(p);
  		Thread t4 = new Thread(c);
  
  		t1.start();
  		t2.start();
  		t3.start();
  		t4.start();
  
  	}
  }

2.中断线程 

    通过让run方法结束可以停止线程,需要在run方法中定义一个结束标记,但是如果线程处于了冻结状态,就无法读取结束标记,线程就不会结束,这时需要使用interrupt()对线程的冻结状态进行清除.    

    interrupt():如果线程在调用Object类的wait()、join()、sleep(long)方法过程中受阻,则其中断状态将被清除(使线程恢复到运行状态),它还将收到一个InterruptedException.

3.守护线程

    setDaemon():将该线程标记为守护线程或用户线程,守护线程就相当于后台线程,当前台线程结束时,后台线程跟着也结束.

class StopThread implements Runnable
{
	public  void run()//原本run方法是一个死循环,但是将线程定义为守护线程后,主线程结束,访问run方法的线程立即也结束了
	{
		while(true)
		{		
			System.out.println(Thread.currentThread().getName()+"....run");
		}
	}
}
class  StopThreadDemo
{
	public static void main(String[] args) 
	{
		StopThread st = new StopThread();	
		Thread t1 = new Thread(st);
		Thread t2 = new Thread(st);
		//将t1,t2定义为守护线程
		t1.setDaemon(true);
		t2.setDaemon(true);
		t1.start();
		t2.start();
		int num = 0;
		while(true)
		{
			if(num++ == 60)
			{
				break;
			}
			System.out.println(Thread.currentThread().getName()+"......."+num);
		}
		System.out.println("over");
	}
}

4.join()

    join()其实就是抢夺cpu的执行权,当A线程执行到了B线程的.join()方法时,A就会等待,等B线程都执行完,A才会继续执行.

class Demo implements Runnable
{
	public void run()
	{
		for(int x=0; x<70; x++)
		{
			System.out.println(Thread.currentThread().getName()+"....."+x);
		}
	}
}
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.join();//t1获取cpu的执行权,主线程处于冻结状态,只有t1结束主线程才能恢复运行状态
		t2.start();
		//t1.join();主线程冻结,t1,t2交替运行,t1结束,主线程才继续
		for(int x=0; x<80; x++)
		{		}
		System.out.println("over");
	}
}

学习感悟

    个人感觉多线程这还是比较抽象的,虽然之前是学理科的,但还是很难理解线程之间的运行模式.线程的通信是一个重点,多个线程操作同一个数据,要保证先有输入才能输出,需要定义一个标示去告诉线程当前有无输入数据,有则停止输入线程开启输出线程,无则停止输出开启输入线程.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值