多线程之同步线程通信小例子

最近在学习多线程的时候,看到这样的一个问题:有两个线程,一个是子线程,一个是主线程,子线程运行10次,接着主线程运行20次,接着子线程运行10,主线程运行20次,依次交替循环20次。刚开始看到这个问题的时候,很是茫然。后来分析一下,子线程和主线程交替运行,这是一个线程在执行的时候,另一个线程在等待状态,当在执行的线程执行完之后,唤醒另外一个线程,这样交替进行。线程在执行的地方是要加锁的。但是,在什么样的场景下会出现这样的情形呢?多线程在同步访问同一个资源的时候。于是写出来的代码如下所示:

package com.zkn.newlearn.thread;

/**
 * Created by zkn on 2016/11/14.
 * 传统的同步通信技术
 * 需求描述:
 *      子线程先运行10次,接着主线程运行20次,
 *      接着子线程运行10次,依次交替反复20次
 * 关键点:共同数据要放到一个类上。
 * 难点:可能想不用操作一个共同的对象来解决。
 * 多线程访问操作共同资源的时候,要在资源的类上进行操作。
 */
public class ThreadSynchronousCommunicationTest01 {

    public static void main(String[] args){
        //确保多线程对共同资源的操作,是操作在资源类上。
        SynchronousCommunication synchronousCommunication = new SynchronousCommunication();
        new Thread(
                new Runnable() {
                    @Override
                    public void run() {
                        for(int i=0;i<20;i++){
                            synchronousCommunication.sub(i);
                        }
                    }
                }
        ).start();
        for(int i=0;i<20;i++){
            synchronousCommunication.main(i);
        }
    }
}

/**
 * 通信类
 */
class SynchronousCommunication{
    /**
     * 线程执行的标记
     */
    private boolean flag = true;

    public synchronized void sub(int i){
        //这里要用while,防止线程被假唤醒
        //如果flag是false,说明主线程在执行,所以子线程要进入等待状态
        while(!flag){
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for(int j=0;j<10;j++){
            System.out.println("子线程第"+i+"遍运行,运行到第"+j+"次");
        }
        //子线程执行完之后,要改变执行标记
        flag = false;
        //唤醒休眠中的线程(即这里的主线程)
        this.notifyAll();
    }

    public synchronized void main(int i){
        //这里要用while,防止线程被假唤醒
        //如果flag是false,说明子线程在执行,所以主线程要进入等待状态
        while (flag) {
            try {
                this.wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        for(int j=0;j<20;j++){
            System.out.println("主线程第"+i+"遍运行,运行到第"+j+"次");
        }
        //主线程执行完之后,要改变执行标记
        flag = true;
        //唤醒休眠中的线程(即这里的子线程)
        this.notifyAll();
    }
}
时间: 2024-08-01 21:14:10

多线程之同步线程通信小例子的相关文章

同步-线程并发中wait()和notify()怎么用的,可不可以举个小例子

问题描述 线程并发中wait()和notify()怎么用的,可不可以举个小例子 线程并发中wait()和notify()怎么用的,可不可以举个小例子,再问一下,线程中阻塞方法有哪些,同步的有哪些? 解决方案 参考:http://longdick.iteye.com/blog/453615

java 多线程-线程通信实例讲解_java

线程通信的目标是使线程间能够互相发送信号.另一方面,线程通信使线程能够等待其他线程的信号. 通过共享对象通信 忙等待 wait(),notify()和 notifyAll() 丢失的信号 假唤醒 多线程等待相同信号 不要对常量字符串或全局对象调用 wait() 通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值.线程 A 在一个同步块里设置 boolean 型成员变量 hasDataToProcess 为 true,线程 B 也在同步块里读取 hasDataToProc

VC中利用多线程技术实现线程之间的通信

文章来源:[url]http://www.programfan.com/article/showarticle.asp?id=2951[/url] 当前流行的Windows操作系统能同时运行几个程序(独立运行的程序又称之为进程),对于同一个程序,它又可以分成若干个独立的执行流,我们称之为线程,线程提供了多任务处理的能力.用进程和线程的观点来研究软件是当今普遍采用的方法,进程和线程的概念的出现,对提高软件的并行性有着重要的意义.现在的大型应用软件无一不是多线程多任务处理,单线程的软件是不可想象的.

java多线程的同步 通信以及生产消费者问题

Demo1 /*   Runable接口比直接从Thread继承方便的多  .  *    new  Thread(...) ;这样即使我们传递了同一个实现了Runnable接口的多个对象那么 也是多个线程 ,而且多个线程共享数据域. *    否则new Thread 创建的多个线程之间 互不相干  ,数据之间互不干涉 *    同步就是为了实现 在多个线程同时对一个资源进行操作的时候 要一个一个的执行 , *    只有等占有CPU的 线程完事之后 其他等待线程才能进入就绪状态等待运行 * 

Java多线程共享数据、同步、通信

一.线程共享数据 a)继承Thread,那么我们可以创建很多个这样的类,但是每个这样的类都是相互不关联的,也就是说我们Thread类中的内容每个创建出来的类都有一份,因此它不适合作为数据共享的线程来操作.同时由于Java继承的唯一性,我们只能继承一个对象. b)使用runnable就可以解决唯一性和不能共享的问题(不是说使用runnable就解决了共享问题,只是相对于创建Thread来说,它可以算的上是共享了,为了获得更精确的共享问题,它必须的使用线程同步操作).实现了runnable接口的类比

c#.net多线程编程教学——线程同步_C#教程

随着对多线程学习的深入,你可能觉得需要了解一些有关线程共享资源的问题. .NET framework提供了很多的类和数据类型来控制对共享资源的访问. 考虑一种我们经常遇到的情况:有一些全局变量和共享的类变量,我们需要从不同的线程来更新它们,可以通过使用System.Threading.Interlocked类完成这样的任务,它提供了原子的,非模块化的整数更新操作. 还有你可以使用System.Threading.Monitor类锁定对象的方法的一段代码,使其暂时不能被别的线程访问. System

vc 基于对话框多线程编程实例——线程之间的通信

 vc基于对话框多线程编程实例--线程之间的通信 实例:  

线程通信

线程通信的目标是使线程间能够互相发送信号.另一方面,线程通信使线程能够等待其他线程的信号. 例如,线程B可以等待线程A的一个信号,这个信号会通知线程B数据已经准备好了.本文将讲解以下几个JAVA线程间通信的主题: 1.通过共享对象通信 2.忙等待 3.wait(),notify()和notifyAll() 4.丢失的信号 5.假唤醒 6.多线程等待相同信号 7.不要对常量字符串或全局对象调用wait() 1.通过共享对象通信 线程间发送信号的一个简单方式是在共享对象的变量里设置信号值.线程A在一

Java线程通信详解_java

线程通信用来保证线程协调运行,一般在做线程同步的时候才需要考虑线程通信的问题. 1.传统的线程通信 通常利用Objeclt类提供的三个方法: wait() 导致当前线程等待,并释放该同步监视器的锁定,直到其它线程调用该同步监视器的notify()或者notifyAll()方法唤醒线程. notify(),唤醒在此同步监视器上等待的线程,如果有多个会任意选择一个唤醒 notifyAll() 唤醒在此同步监视器上等待的所有线程,这些线程通过调度竞争资源后,某个线程获取此同步监视器的锁,然后得以运行.