黑马程序员_源自梦想 线程2

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

守护线程

o.必须通过setDaemon(true)进行设置;
a.所谓守护线程就是运行在程序后台的线程,程序的主线程Main不会是守护线程.
b.默认产生的线程全部是Non-daemon线程.
c.主线程main一结束,jvm停止了,守护线程也就结束了。(会伴随着main消亡,而不是一起而生)
/*stop方法已经过时。
如何停止线程?
只有一种,run方法结束。
开启多线程运行,运行代码通常是循环结构。
只要控制住循环,就可以让run方法结束,也就是线程结束。
特殊情况:
当线程处于了挂起状态。
就不会读取到标记。那么线程就不会结束。

a.Thread类提供该方法 interrupt();
b.通过setDaemon(true);转为守护线程
*/
class StopThread implements Runnable
{
	private boolean flag =true;
	public  void run()
	{
		while(flag)
		{
			try {
				Thread.sleep(10);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"....run"  );
		}
	}
	public void changeFlag()
	{
		flag = false;
	}
}
class  StopDemo
{
	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)
			{
				try {
					Thread.sleep(10);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				//st.changeFlag();
				//t1.interrupt();
				//t2.interrupt();
				break;
			}
			System.out.println(Thread.currentThread().getName()+"......."+num);
		}
		System.out.println("over");	
	}
}

sleep与yield的区别

不同点:
a.Thread.sleep(long millis)必须带有一个时间参数的<------>yield()不带参数的
b.sleep() 方法不管优先级高低,线程获得运行机会<------>yield()方法只能让同优先级的线程有执行的机会。
c.sleep()会抛出InterruptedException异常,而yield不会抛出异常。
d.sleep比yield方法有更好的可移植性,通常,不要依靠yield控制并发线程的执行。
相同点:都不会释放锁标志。

join:

A.join()只有A线程执行完,才能执行其他线程;
A.join(1000) 等一秒后,让出当前线程(不管有没有执行完)
class JoinThread implements Runnable
{
	public  void run()
	{
		for(int i = 0; i < 30; i++){
			
			if(i++  % 10 == 0){
				try {
					Thread.currentThread().join(100);
					System.out.println(Thread.currentThread().getName());
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}

}

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

		t1.start();
		t2.start();
	}
}
//----------结果----------
Thread-1
Thread-0
Thread-0
Thread-1
Thread-1
Thread-0

案例 --银行 --生产者和消费者

/*
需求:
银行有一个金库。
有两个用户分别存200,每次存100,存2次。
目的:该程序是否有安全问题,如果有,如何解决?
如何找问题:
1,明确哪些代码是多线程运行代码。
2,明确共享数据。-->(钱)
3,明确多线程运行代码中哪些语句是操作共享数据的。
*/
class Bank
{
	private int sum;
	public synchronized void add(int n)
	{
		//synchronized(this){ 
			sum = sum + n;
			try{Thread.sleep(10);}catch(Exception e){}
			System.out.println("sum="+sum);
		//}
	}
}
class Manipulation  implements Runnable
{
	private Bank b = new Bank();
	public void run()
	{		
		for(int x=0; x<2; x++)
		{
			b.add(100);
		}
	}
}
class  BankDemo
{
	public static void main(String[] args) 
	{
		Manipulation c = new Manipulation();
		Thread t1 = new Thread(c);
		Thread t2 = new Thread(c);
		t1.start();
		t2.start();
	}
}
/*
对于多个生产者和消费者。
为什么要定义while判断标记。
原因:让被唤醒的线程再一次判断标记。

为什么定义notifyAll,
因为需要唤醒对方线程。
因为只用notify,容易出现只唤醒本方线程的情况。导致程序中的所有线程都等待。
*/
package com.cwk.inner;
class Resource
{
	private String name;
	private int count = 1;
	private boolean flag = false;
		
	public synchronized void set(String name)
	{
		while(flag)
			try{this.wait();
			Thread.sleep(500);
			}catch(Exception e){}
		this.name = name+"--"+count++;

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

class Producer implements Runnable
{
	private Resource res;

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

class Consumer implements Runnable
{
	private Resource res;

	Consumer(Resource res)
	{
		this.res = res;
	}
	public void run()
	{
		while(true)
		{
			res.out();
		}
	}
}
public class NotifyDemo {
	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();
	}
}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值