java多线程之间的通信

如何让两个线程依次执行?
那如何让 两个线程按照指定方式有序交叉运行呢?
四个线程 A B C D,其中 D 要等到 A B C 全执行完毕后才执行,而且 A B C 是同步运行的
三个运动员各自准备,等到三个人都准备好后,再一起跑
子线程完成某件任务后,把得到的结果回传给主线程
1.如何让两个线程依次执行?#
Copy
public static void main(String[] args) {
demo1();
/
结果: t1>>pirnt:1
t2>>pirnt:1
t2>>pirnt:2
t1>>pirnt:2
t1>>pirnt:3
t2>>pirnt:3
/
demo1_1();
/
结果:
t1>>pirnt:1
t1>>pirnt:2
t1>>pirnt:3
t2>>pirnt:1
t2>>pirnt:2
t2>>pirnt:3
/
}

public static void demo1() {
    // 线程一
    final Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            printNumber("t1");
        }
    });

    // 线程二
    final Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            printNumber("t2");
        }
    });

    // 启动线程
    t1.start();
    t2.start();
}

public static void demo1_1() {
    // 线程一
    final Thread t1 = new Thread(new Runnable() {
        @Override
        public void run() {
            printNumber("t1");
        }
    });

    // 线程二
    final Thread t2 = new Thread(new Runnable() {
        @Override
        public void run() {
            // 等到线程一执行完,再执行线程二
            try {
                t1.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            printNumber("t2");
        }
    });

    // 启动线程
    t1.start();
    t2.start();
}

/**
 * 线程调用的方法
 * @param threadName
 */
public static void printNumber(String threadName) {
    int i = 0;
    while (i++ < 3) {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        System.out.println(threadName+">>pirnt:"+i);
    }
}
  1. 那如何让 两个线程按照指定方式有序交叉运行呢?#
    这里可以使用同一个锁控制,然后调用wait()方法,和notify()方法
    线程一打印1,然后线程二打印1,2,3 线程一在打印2,3

Copy
public static void demo2() {
// 创建一个对象,用来作为锁
final Object objLock = new Object();

        //线程一
        Thread t1 = new Thread(new Runnable() {
            @Override
            public void run() {
                // 同步代码块
                synchronized (objLock){
                    System.out.println("t1>>print:1");
                    try {
                        objLock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    // 线程二执行完,唤醒线程一
                    System.out.println("t1>>print:2");
                    System.out.println("t1>>print:3");
                }
            }
        });

        // 线程二
        Thread t2 = new Thread(new Runnable() {
            @Override
            public void run() {
                synchronized (objLock) {
                    // 线程二输出内容
                    System.out.println("t2>>print:1");
                    System.out.println("t2>>print:2");
                    System.out.println("t2>>print:3");
                    // 唤醒wait中的线程
                    objLock.notify();
                }
            }
        });

        // 启动线程
        t1.start();
        t2.start();

    }

 结果:
 t1>>print:1
 t2>>print:1
 t2>>print:2
 t2>>print:3
 t1>>print:2
 t1>>print:3

3.四个线程 A B C D,其中 D 要等到 A B C 全执行完毕后才执行,而且 A B C 是同步运行的#
1) 创建一个计数器,设置初始值,CountdownLatch countDownLatch = new CountDownLatch(2);
2) 在 等待线程 里调用 countDownLatch.await() 方法,进入等待状态,直到计数值变成 0;
3) 在 其他线程 里,调用 countDownLatch.countDown() 方法,该方法会将计数值减小 1;
4) 当 其他线程 的 countDown() 方法把计数值变成 0 时,等待线程 里的 countDownLatch.await() 立即退出,继续执行下面的代码。
CountDownLatch 适用于一个线程去等待多个线程的情况。

Copy
public static void runDAfterABC() {
// 定义计数器的计数值
int worker = 3;
// 创建计数器
final CountDownLatch countDownLatch = new CountDownLatch(worker);

        // 创建线程D
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println("D线程等待ABC线程运行。。。。");
                try {
                    // 线程等待
                    countDownLatch.await();
                    System.out.println("ABC线程运行完,D线程运行");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

        // 创建ABC线程
        for (char threadName=‘A‘; threadName<=‘C‘; threadName++) {
            // char转换为String
            final String tN = String.valueOf(threadName);

            //创建线程
            new Thread(new Runnable() {
                @Override
                public void run() {
                    System.out.println("线程"+tN+"运行中。。");
                    try {
                        Thread.sleep(100);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("线程"+tN+"结束");
                    // 计数器减一
                    countDownLatch.countDown();
                }
            }).start();
        }
    }

    结果:

    D线程等待ABC线程运行。。。。
    线程A运行中。。
    线程C运行中。。
    线程B运行中。。
    线程A结束
    线程C结束
    线程B结束
    ABC线程运行完,D线程运行

?
?

  1. 线程 A B C 各自开始准备,直到三者都准备完毕,然后再同时运行#
    1) 先创建一个公共 CyclicBarrier 对象,设置 同时等待 的线程数,CyclicBarrier cyclicBarrier = new CyclicBarrier(3);

2)这些线程同时开始自己做准备,自身准备完毕后,需要等待别人准备完毕,这时调用 cyclicBarrier.await();即可开始等待别人;

3) 当指定的 同时等待 的线程数都调用了 cyclicBarrier.await();时,意味着这些线程都准备完毕好,然后这些线程才 同时继续执行。

Copy
public static void runABCWhenAllReady() {
// 定义运行线程数
int runner = 3;

        // 创建CyclicBarrier 对象
        final CyclicBarrier cyclicBarrier = new CyclicBarrier(runner);
        // 创建随机数类,产生准备时间
        final Random random = new Random();
        // 创建线程
        for (char threadName=‘A‘; threadName <= ‘C‘; threadName++) {
            final String tN = String.valueOf(threadName);
            new Thread(new Runnable() {
                @Override
                public void run() {
                    // 随机生成准备时间
                    long prepareTime = random.nextInt(1000)+100;
                    System.out.println("线程"+tN+"准备中。。");

                    try {
                        Thread.sleep(prepareTime);
                        System.out.println("线程"+tN+"准备完成,等待其他线程!");
                        // 线程准备完毕
                        cyclicBarrier.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    } catch (BrokenBarrierException e) {
                        e.printStackTrace();
                    }
                    // 所有线程准备好后,运行
                    System.out.println("线程"+tN+"运行中。。");
                }
            }).start();
        }
    }

    结果:
    线程A准备中。。
    线程B准备中。。
    线程C准备中。。
    线程A准备完成,等待其他线程!
    线程C准备完成,等待其他线程!
    线程B准备完成,等待其他线程!
    线程A运行中。。
    线程B运行中。。
    线程C运行中。。
  1. 子线程运行完后,将结果返回给主线程#
    实现接口类:Callable,在 v call()方法中编写运行代码

将结果返回主线程,使用 FutureTask 类的 get 方法,将数据传回去,

get方法会阻塞线程,然后call方法执行

Copy
public static void doTaskWithResultInWorker() {
// 创建Callable对象
Callable<Integer> callable = new Callable<Integer>() {br/>@Override
public Integer call() throws Exception {
// 创建任务
System.out.println("任务开始");
int result = 0;
for (int i=0; i<=100; i++) {
result += i;
}
System.out.println("任务结束,返回结果");
// 返回结果
return result;
}
};

        // 创建FutureTask,获取返回值
        FutureTask<Integer> futureTask = new FutureTask<Integer>(callable);
        // 启动线程
        new Thread(futureTask).start();

        // 线程阻塞,获取返回值
        try {
            System.out.println("结果:"+futureTask.get());
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
    }

    结果:
    任务开始
    任务结束,返回结果
    结果:5050

java多线程之间的通信

原文地址:https://blog.51cto.com/14735798/2476218

时间: 2024-10-10 12:39:36

java多线程之间的通信的相关文章

多线程之间的通信(等待唤醒机制、Lock 及其它线程的方法)

一.多线程之间的通信. 就是多个线程在操作同一份数据, 但是操作的方法不同. 如: 对于同一个存储块,其中有两个存储位:name   sex, 现有两个线程,一个向其中存放数据,一个打印其中的数据. 为了解决上述问题中的安全问题(在存放线程进行存放操作的时候, 打印线程不能对共有数据进行操作),所以应当对两个线程       操作共有数据的代码部分进行同步(使用synchronized(),来进行同步, 注意 :使用同一个对象作为同步锁. 二.等待唤醒机制. 在上述案例实现过后运行,会发现:打印

多线程之间的通信实例讲解

                 多线程之间的通信实例讲解对于线程来说,说白了,就是一个函数,如果大家对于这章函数都有理解,那我对于操作系统,线程和进程间的通信会有一个新的认识!接下来我会对每一行代码进行注释,在此过程中,大家也可以对c语言有一个崭新的认识. 第一个函数,创建两个线程. #include <stdio.h>#include <pthread.h>    这个头函数要包含,因为我们后续用的函数都是系统调用,因此需要申请头函数   这样在编译的时候,就可以找到此函数的源

java线程之间的通信

1.常用的方法 sleep()该线程进入等待状态,不释放锁 wait() 该线程进入等待状态,释放锁 notify() 随机唤醒一个线程 notifyAll() 唤醒全部线程 2.线程之间的通信 a.两个线程之间的通信 public class ThreadExchange { @Test public void test2Thread() { MyPrint myPrint = new MyPrint(); new Thread(new Runnable() { @Override publi

JAVA多线程之间共享数据BlockingQueue介绍

在JAVA的Concurrent包中,BlockingQueue很好的解决了多线程中,如何高效安全“传输”数据的问题.通过这些高效并且线程安全的队列类,为我们快速搭建高质量的多线程程序带来极大的便利.本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景. 一.认识BlockingQueue 阻塞队列,顾名思义,首先它是一个队列,而一个队列在数据结构中所起的作用大致如下图所示:  从上图我们可以很清楚看到,通过一个共享的队列,可以使得数据由队列的一端输入,从

Java多线程间的通信问题扩展

到底什么是线程间的通信? 线程间需要通过一些协调性的通信,实现共同完成同一件任务,简单说就是,你想做这件事,我也想做这件事,我们两个相互交流,共同做这件事,而共同任务的同步性的实现,就必须通过同步锁,每一个对象实例都有自己的一把锁,当一个线程想要对这个任务进行处理的时候,就必须获得这把锁.线程之间锁的释放与获取,是通过Object类中的wait()/notify()方法实现的.wait()方法是将当前拥有锁的线程至于等待状态让其释放锁,而notify()方法是唤醒其他线程使其具备执行资格,过来拿

黑马程序员————java线程之间的通信

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- 多线程可以让我们同时共享一个资源,但如果在共享这个资源时需要彼此之间的联系怎么做呢? 经典实例:生产者与消费者. 问题描述,生产者每生产一个消费者就要取走一个,同时进行. 首先java为我们提供了一套等待唤醒机制,让线程与线程之间产生了联

多线程之间的通信

线程通信的概念: 线程是操作系统中独立的个体,但这些个体如果不经过特殊的处理就不能成为一个整体,线程间的通信就成为整体的必用方式之一.当线程存在通信指挥,系统间的交互性会更强大,在提高CPU利用率的同时还会使开发人员对线程任务在处理的过程中进行有效的把控与监督. 使用wait/notify方法实现线程间的通信(这两个方法都是object的类的方法,换句话说java为所有的对象 都提供了这两个方法)1.1.wait和notify必须配合synchronized关键字使用 2.wait方法释放锁,n

Java多线程之线程通信

线程通信的例子:使用两个线程打印 1-100,线程1.线程2交替打印.涉及到的三个方法:wait():一旦执行此方法,当前线程就进入阻塞状态,并释放同步监视器.notify():一旦执行此方法,就会唤醒被wait的一个线程.如果有多个线程被wait,就唤醒优先级高的那个.notifyAll():一旦执行此方法,就会唤醒所有被wait的线程. 说明:1.wait(),notify(),notifyAll()三个方法必须使用在同步代码块或同步方法中.2.wait(),notify(),notifyA

java 多线程 day04 线程通信

package com.czbk.thread; /** * Created by chengtao on 17/12/3. * 需求: 子线程先运行10次,然后主线程运行 100次,依次运行50次 * wait(): 等待 如果线程执行了wait方法,那么该线程会进入等待的状态,等待状态下的线程必须要被其他线程调用notify方法才能唤醒. notify(): 唤醒 唤醒线程池等待线程其中的一个. notifyAll() : 唤醒线程池所有等待 线程. wait与notify方法要注意的事项: