前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >并发编程之线程协作

并发编程之线程协作

作者头像
爱撒谎的男孩
发布2019-12-31 15:08:08
2300
发布2019-12-31 15:08:08
举报
文章被收录于专栏:码猿技术专栏码猿技术专栏

文章目录

1. 并发编程之线程协作

1.1. wait / notify / notifyAll

1.1.1. 实例

1.2. 条件变量condition

1.3. 倒计时协调器 CountDownLatch

1.4. 栅栏 CycliBarrier

1.5. 阻塞队列BlockingQueue

1.6. 信号量Semaphore

1.7. 参考文章

并发编程之线程协作

wait / notify / notifyAll

  • Object.wait()/Object.notify()/Object.notifyAll()可用于实现等待和通知。
  • wait()方法可以使其执行的线程被暂停,该方法用来实现等待。
    • 进入阻塞状态(Block)
    • 只有在持有一个对象的锁的时候才可以调用wait()方法,因此Object.wait()总是放在相应对象所领导的临界区中,必须和synchronized关键字进行使用
    • 在执行wait方法的同时也会释放同步锁,从而线程进入阻塞状态
  • notify()用于唤醒一个被暂停的线程,调用该方法可以实现通知
    • 必须使用和wait()方法一样的对象调用
    • 必须使用synchronized关键字,并且在执行完毕之后会释放同步锁
    • 唤醒的是当前对象上的任意一个等待的线程
    • 被唤醒的等待线程在其占用的处理器继续运行的时候,需要再次申请Object对应的内部锁(synchronized)
  • notifyAll() 用于唤醒当前对象中的全部等待线程

实例

public class TestThread {
	public static void main(String[] args) throws InterruptedException {
		MyThread thread=new MyThread();
		new Thread(thread,"线程1").start();
		Thread.sleep(2000);
		thread.testNotifyAll();
	}
	
}
class MyThread implements Runnable{
	private final Object object=new Object();  //创建一个Object对象,用于线程同步锁和调用wait方法
	private volatile boolean flag=true;   //保护条件
	private int count=0;
	public void run() {
		this.testWait();
	}
	
	//测试等待
	public void testWait(){
		//循环执行
		while(true){
            //必须和调用wait的方法是一个对象
			synchronized (object) {
				while(!this.flag){
					try {
						System.out.println(Thread.currentThread().getName()+" 等待被唤醒....");
						object.wait();
					} catch (InterruptedException e) {
						System.out.println("线程被终止.....");
					}
				}
				this.doAction();  //执行其他的动作
			}
		}
	}
	
	//测试唤醒线程,随机唤醒一个线程
	public void testNotify(){
		synchronized (object) {
			this.flag=true;  
			//从当前object的等待线程中随机唤醒一个线程
			object.notify();
		}
	}
	
	//唤醒所有线程
	public void testNotifyAll(){
		synchronized (object) {
			this.flag=true;
			object.notifyAll();  //唤醒当前对象上的所有等待线程
		}
	}
	
	//执行其他动作
	public void doAction(){
		System.out.println("执行其他的功能");
		count++;
		if (count==10) {
			flag=false;   //改变flag的值 ,将会wait
		} 
	}
}

条件变量condition

  • wait,notify()思想一样,不过这个要和显示锁Lock结合使用
public class TestThread {
	private static final  Lock lock=new ReentrantLock();  //创建显示锁
	private  static final Condition condition=lock.newCondition();  //创建条件变量
	private  static volatile boolean flag=true;   //保护条件
	public static void main(String[] args) throws InterruptedException {
		Thread thread1=new Thread(){
			public void run() {
				testWait();
			};
		};
		thread1.start();
		
		
		Thread thread2=new Thread(){
			public void run() {
				testSignal();
			};
		};
		thread2.start();
		
		
		
		
	}
	public static void testWait(){
		while(true){
			lock.lock();  //获取显示锁
			try {
				if (!flag) {
					condition.await();
				}
				doAction();
			} catch (InterruptedException exception) {
				exception.printStackTrace();
			}finally{
				lock.unlock();  //释放锁
			}
		}
	}
	
	public static void testSignal(){
		while(true){
			lock.lock();  //获取锁
			try {
				if (flag) {
					System.out.println("执行其他的动作");
				}else {
					flag=true;
					Thread.sleep(5000);
					condition.signal();  //唤醒线程
				}
			} catch (Exception e) {
				e.printStackTrace();
			}finally{
				lock.unlock();
			}
		}
	}
	
	public static void doAction(){
		System.out.println("执行其他的动作");
		flag=false;  //改变flag
	}
		
}

倒计时协调器 CountDownLatch

栅栏 CycliBarrier

阻塞队列BlockingQueue

信号量Semaphore

参考文章

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2018-06-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 并发编程之线程协作
    • wait / notify / notifyAll
      • 实例
    • 条件变量condition
      • 倒计时协调器 CountDownLatch
        • 栅栏 CycliBarrier
          • 阻塞队列BlockingQueue
            • 信号量Semaphore
              • 参考文章
              领券
              问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档