Java 线程同步方式 wait/notify(两个线程交替执行的例子)

线程同步,就是线程之间互相协调,通过等待,唤醒等操作,避免线程之间同时操作同一个资源。简单的说就是线程之间互相协作,避免干扰了其他线程的工作。

Java 线程中,有多种方式可以实现线程同步,wait/notify 方法是最常用的一种方式。

实现 2 个线程,一个线程只能打印奇数,另一个线程只能打印偶数,现在需要打印出 1234…..100 这样的数列。

下面代码的一种实现方式,未有任何同步机制,所以两个线程不可能交替运行。

 public static void main(String args[]) throws Exception {
        FutureTask task1=new FutureTask(()->{
            for(int i=0;i<50;i++)
            {
                System.out.print(i*2+1+",");
            }
            return null;
        });
        Thread t1=new Thread(task1);
 
        FutureTask task2=new FutureTask(()->{
            for(int i=0;i<50;i++)
            {
                System.out.print(i*2+2+",");
            }
            return null;
        });
        Thread t2=new Thread(task2);
 
        t1.start();
        t2.start();
        t1.join();
        t2.join();
    }

下面的代码,通过 synchronized 关键字,wait 方法阻塞,notify 方法唤醒的方式,实现线程之间的通信。

public static void main(String args[]) throws Exception {
        Object lock = new Object();
        final boolean[] flag = {true};//交替执行标志位。true-线程1运行,false-线程2运行
        FutureTask task1 = new FutureTask(() -> {
            for (int i = 0; i < 50; i++) {
                synchronized (lock) {
                    while (true) {
                        if (flag[0]) {
                            System.out.print(i * 2 + 1 + ",");
                            flag[0] = false;
                            lock.notify();
                            if (i < 49) {//打印完最后一个,不需要再wait了。
                                lock.wait();
                            }
                            break;
                        }
                    }
                }
            }
            return null;
        });
        Thread t1 = new Thread(task1);
 
        FutureTask task2 = new FutureTask(() -> {
            for (int i = 0; i < 50; i++) {
                synchronized (lock) {
                    while (true) {
                        if (!flag[0]) {
                            System.out.print(i * 2 + 2 + ",");
                            flag[0] = true;
                            lock.notify();
                            if (i < 49) {//打印完最后一个,不需要再wait了。
                                lock.wait();
                            }
                            break;
                        } else {
                            lock.wait();
                        }
                    }
                }
            }
            return null;
        });
        Thread t2 = new Thread(task2);
 
        t1.start();
        t2.start();
        t1.join();
        t2.join();
        System.out.print("finished");
    }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏前端布道

MongoDB初识

什么是MongoDB MongoDB 是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。 在高负载的情况下,添加更多的节点,可以保证服务器性能。 ...

3918
来自专栏技术博文

Linux下各种压缩与解压

1、zip格式 压缩: zip -r [目标文件名].zip [原文件/目录名] 解压: unzip [原文件名].zip 注:-r参数代表递归 2、tar格...

4066
来自专栏CRPER折腾记

Angular 2 + 折腾记 :(5) 动手实现一个自定义管道

一般是用于Mustache语法的双向数据内,eg: {{item | json}}

972
来自专栏Python绿色通道

Python的线程

Python的标准库提供了两个模块: thread 和threading,thread 是低级模块,threading是高级模块,对thread 进行了封装。绝...

1683
来自专栏Python绿色通道

Python的进程

Python实现多进程的方式主要有两种:一种方法是使用os模块中的fork方法; 另一种是使用multiprocessing模块。这两种方法的区别在于前者仅适用...

1092
来自专栏思考的代码世界

Python基础学习09天

1756
来自专栏武军超python专栏

2018年8月25日python中os模块和sys模块的区别

    os: This module provides a portable way of using operating system dependent ...

1853
来自专栏破晓之歌

Python中os与sys两模块的区别 原

os: This module provides a portable way of using operating system dependent func...

681
来自专栏C/C++基础

Linux命令(1)——xargs命令

xargs可以将stdin中以空格或换行符进行分隔的数据,形成以空格分隔的参数(arguments),传递给其他命令。因为以空格作为分隔符,所以有一些文件名或者...

1553
来自专栏积累沉淀

干货--Redis 30分钟快速入门

一、 redis环境搭建 1.简介        redis是一个开源的key-value数据库。它又经常被认为是一个数据结构服务器。因为它的value不仅...

32610

扫码关注云+社区

领取腾讯云代金券