黑马程序员_多线程2

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

死锁:一旦产生程序就停在那儿不动了,没法继续执行下去。

死锁的出现:同步中嵌套同步
比如:同步函数中有同步代码块,同步代码块中有同步函数
面试的时候有可能让你写个死锁的例子:
下面给个线程死锁的例子:
class Test implements Runnable{
	
	private boolean flag;
	Test(boolean flag){
		this.flag = flag;
	}
	public void run(){
		if(flag){
			synchronized (MyLock.locka) {
				System.out.println("if locka");
				synchronized (MyLock.lockb) {
					System.out.println("if lockb");
				}
			}
		}else{
			synchronized (MyLock.lockb) {
				System.out.println("else locka");
				synchronized (MyLock.locka) {
					System.out.println("else lockb");
				}
			}
		}
	}	
}
class MyLock{
	static Object locka = new Object();
	static Object lockb = new Object();
}
public class DeadLockTest {
	public static void main(String[] args) {
		Thread t1 =new Thread(new Test(true));
		Thread t2 =new Thread(new Test(false));
		t1.start();
		t2.start();
	}
}


线程间通讯:其实就是多个线程在操作同一个资源,但是操作的动作不同
实现一个简单的小功能:一个往对象里面一直在加入东西一个一直往对象外面一直拿东西
只有存进去以后才能往外面拿,只有拿出了以后才能存
代码示例:

class Test implements Runnable{
	
	private boolean flag;
	Test(boolean flag){
		this.flag = flag;
	}
	public void run(){
		if(flag){
			synchronized (MyLock.locka) {
				System.out.println("if locka");
				synchronized (MyLock.lockb) {
					System.out.println("if lockb");
				}
			}
		}else{
			synchronized (MyLock.lockb) {
				System.out.println("else locka");
				synchronized (MyLock.locka) {
					System.out.println("else lockb");
				}
			}
		}
	}	
}
class MyLock{
	static Object locka = new Object();
	static Object lockb = new Object();
}
public class DeadLockTest {
	public static void main(String[] args) {
		Thread t1 =new Thread(new Test(true));
		Thread t2 =new Thread(new Test(false));
		t1.start();
		t2.start();
	}
}

唤醒全部线程的话可以用notifyAll();
wait(),notify(),notifyAll(),都使用在同步总,因为要对
持有监视器(锁)的线程操作,所以要使用在同步中,因为只有同步才具有锁。
为什么这些操作线程的方法要定义Object类中呢?
因为这些方法在操作同步中线程时,都必须要标识它们所操作线程只有的锁,
只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒。
不可以对不同锁中的线程进行唤醒
也就是说,等待和唤醒必须是同一个锁
而锁可以是任意对象,所以可以被任意对象调用的方法定义object类中
生产者消费者模式:


public class Test {
	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(con);
		
		t1.start();
		t2.start();
	}
}
class Resource{
	private String name ;
	private int count =1;
	private boolean flag = false;
	public synchronized void set(String name ){
		if(flag)
			try {
				this.wait();
			} catch (Exception e) {
			}
		this.name = name +"---"+count++;
		System.out.println(Thread.currentThread().getName()+"......生产者......."+this.name);
			flag = true;
			this.notify();
	}
	public synchronized void out(){
		if(!flag)
			try {
				wait();
			} catch (Exception e) {
			}
		System.out.println(Thread.currentThread().getName()+".......消费者....."+this.name);
		flag = false;
		this.notify();
	}
}
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.set("+商品“+");
		 }
	 } 
}


这个程序在线程大于2的时候会出现问题
if(flag)当出现超过两个以上的线程时,容易唤醒本方,引文
if只执行一次,所以需要换成while(flag),而while(flag)容易出现死锁
所以这时需要this.notifyAll()唤醒所有等待的线程。
Lock实现提供了比使用synchronized方法和语句可获得的更广泛的锁定操作。
Lock是1.5以后升级才出现的
Condition 将 Object 监视器方法(wait、notify 和 notifyAll)分解成截然不同的对象,以便通过将这些对象与任意 Lock 实现组合使用,为每个对象提供多个等待 set(wait-set)。其中,Lock 替代了 synchronized 方法和语句的使用,
Condition 替代了 Object 监视器方法的使用。
使用lock和condition写生产者消费者模式 
class Resource{
	private String name ;
	private int count =1;
	private boolean flag = false;
	private Lock lock = new ReentrantLock();
	private Condition condition = lock.newCondition();
	public  void set(String name ) throws Exception{
		lock.lock();
		try {
			while(flag)
				condition .await();
			this.name = name +"---"+count++;
			System.out.println(Thread.currentThread().getName()+"......生产者......."+this.name);
			flag = true;
		}finally{
			lock.unlock();
		}
	}
	public synchronized void out(){
		
		lock.lock();
		try {
		while(!flag)
			
				condition.await();
				System.out.println(Thread.currentThread().getName()+".......消费者....."+this.name);
				flag = false;
			} finally{
		
				lock.unlock();
	}
}
class Producer implements Runnable{
		private Resource res;
		 Producer(Resource res) {
			this.res = res;
		}
		 public void run(){
			 while(true){
				 res.set("+商品“+");
			 }
		 }
}
Lock使用的官方文档:
 Lock l = ...; 
     l.lock();
     try {
         // access the resource protected by this lock
     } finally {
         l.unlock();
     }


如果需要定义只唤醒自己的,则可以定义多个condition
private Condition condition_pro = lock.newCondition();
private Condition condition_con = lock.newCondition();
	    condition_pro .await();
		condition_con.signal();//唤醒对方的线程


线程的停止:stop方法已经过时,那么现在如何停止线程呢
只有一种方式,run方法结束,开启多线程运行,运行代码通常都是循环结构,
只要控制住循环,就可以让run方法结束,也就是线程结束。
特殊情况:当线程处于了冻结状态,就不会读取到标记,那么线程就不会结束。
当没有指定的方式让冻结的线程回复到运行状态时,这时需要对冻结进行清除
强制让线程恢复到运行状态中来,这样就可以操作标记让线程结束
Thread类中提供了该方法叫:interrupt()可以让一个线程处于中断状态
Thread t2 = new Thread(t1);
t2.join();
t2抢夺线程的执行权,只有当t2这个线程运算完了以后主线程才能执行
join:当A线程执行到了B线程的.join()方法时,A就会等待,等
B线程执行完了以后才会执行A线程
join可以用来临时加入线程
setPriority()可以设置线程的优先级,主线程和其它线程默认的是5
优先级1、5、10最明显
MAX_PRIORITY(10)  MIN_PRIORITY(1)  NORN_PRIORITY(5)
yieId() 暂停当前正在执行的线程对象,并执行其他线程
黑马程序员多线程练习题主要包括两个问题。第一个问题是如何控制四个线程在打印log之前能够同时开始等待1秒钟。一种解决思路是在线程的run方法中调用parseLog方法,并使用Thread.sleep方法让线程等待1秒钟。另一种解决思路是使用线程池,将线程数量固定为4个,并将每个调用parseLog方法的语句封装为一个Runnable对象,然后提交到线程池中。这样可以实现一秒钟打印4行日志,4秒钟打印16条日志的需求。 第二个问题是如何修改代码,使得几个线程调用TestDo.doSome(key, value)方法时,如果传递进去的key相等(equals比较为true),则这几个线程应互斥排队输出结果。一种解决方法是使用synchronized关键字来实现线程的互斥排队输出。通过给TestDo.doSome方法添加synchronized关键字,可以确保同一时间只有一个线程能够执行该方法,从而实现线程的互斥输出。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [黑马程序员——多线程10:多线程相关练习](https://blog.csdn.net/axr1985lazy/article/details/48186039)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值