• Java 线程间通讯(共享变量方式)


    Java线程间通讯,最常用的方式便是共享变量方式,多个线程共享一个静态变量就可以实现在线程间通讯,但是这需要注意的就是线程同步问题。

    一、没考虑线程同步:

    package com.wyf;
    
    public class threadConnetcion {
        public static void main(String[] args) {
    
            Q q=new Q();
            //创建生产者线程
            Producer p = new Producer(q);
            
             //创建消费者线程
            Consumer c = new Consumer(q);
            /**
             * 启动线程
             */
            p.start();
            c.start();
        }
    
    }
    
    //生产者线程
    class Producer extends Thread { Q q; public Producer(Q q) { this.q = q; } public void run() { try { int i=0; while(true) { this.sleep(3000); q.put(i++); } } catch (Exception e) { e.printStackTrace(); } } } //消费者线程
    class Consumer extends Thread { Q q; public Consumer(Q q) { this.q = q; } public void run() { try { while(true) { this.sleep(3000); q.get(); } } catch (Exception e) { e.printStackTrace(); } } } class Q { int n; synchronized int get() { System.out.println("Get:"+n); return n; } synchronized void put(int n) { this.n=n; System.out.println("Put:"+n); } }

    输出如下:

    Put:0
    Get:0
    Get:0
    Put:1
    Put:2
    Get:2
    Get:2
    Put:3
    Get:3
    Put:4
    Put:5
    Get:5
    Put:6
    Get:6
    Get:6
    Put:7
    Put:8
    Get:8

    可以看到线程之间的通讯是杂乱的;

    二、使用wait和notify进行线程同步:

    package com.wyf;
    
    public class threadConnetcion {
        public static void main(String[] args) {
    
            Q q=new Q();
            //创建生产者线程
            Producer p = new Producer(q);
            
             //创建消费者线程
            Consumer c = new Consumer(q);
            /**
             * 启动线程
             */
            p.start();
            c.start();
        }
    
    }
    
    //生产者线程
    class Producer extends Thread { Q q; public Producer(Q q) { this.q = q; } public void run() { try { int i=0; while(true) { this.sleep(3000); q.put(i++); } } catch (Exception e) { e.printStackTrace(); } } } //消费者线程
    class Consumer extends Thread { Q q; public Consumer(Q q) { this.q = q; } public void run() { try { while(true) { this.sleep(3000); q.get(); } } catch (Exception e) { e.printStackTrace(); } } } class Q { int n; boolean valueSet=false; synchronized int get() { while(!valueSet) { try { wait(); } catch (Exception e) { e.printStackTrace(); } } System.out.println("Get:"+n); valueSet=false; notify(); return n; } synchronized void put(int n) { while(valueSet) { try { wait(); } catch (Exception e) { e.printStackTrace(); } } this.n=n; System.out.println("Put:"+n); valueSet=true; notify(); } }

    输出如下:

    Put:0
    Get:0
    Put:1
    Get:1
    Put:2
    Get:2
  • 相关阅读:
    一些程序员必备的英语词汇及释义
    ETL工具Talend最佳实践
    spark-submit使用yarn cluster模式时如何获取applicationId?
    On-heap vs Off-heap 堆内内存与堆外内存
    【Kail 学习笔记】kali信息搜集工具之IKE-Scan
    【Kail 学习笔记】kali信息搜集工具之Sparta(斯巴达)
    渗透常用命令
    渗透测试中常用WINDOWS命令
    Jvoke:Java环境下调用系统命令
    SpringCloud以及Nacos服务注册IP选择问题
  • 原文地址:https://www.cnblogs.com/king1302217/p/3158940.html
Copyright © 2020-2023  润新知