• 线程间的互斥与通信


    1.多线程编程中操作共享资源会涉及到多线程安全问题,生活中我们可以用银行转账的例子,用代码来展示如下:

    public class MutexTest {
        public static void main(String[] args) {
            final Writer writer = new Writer();
            new Thread(new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    while (true) {
                        writer.write("aaaaaaaaaa");
                    }
                }
            }).start();
            new Thread(new Runnable() {
                public void run() {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    while (true) {
                        writer.write("bbbbbbb");
                    }
                }
            }).start();
        }
    
    
    }
    
    class Writer {
        public synchronized void write(String string) {
            for (int i = 0; i < string.length(); i++) {
                System.out.print(string.charAt(i));
            }
            System.out.println();
        }
    }

    运行结果:

    我们的理想状态为:aaaaaa打印完以后在打印bbbbbb 现在出现了隔断现象。

    解决:在write方法上添加synchronized或者把需要互斥的代码放在synchronized块中。方法上和同步代码块上加的锁对象都是this,要实现互斥那么加的锁对象一定要相同。如果方法上加上了static关键字此时的锁对象是该类的字节码对象。

    2.线程间的通信

    在1中已经解决了线程安全问题,但是如果我们希望 线程A和线程B友好的运行,即希望线程A打印一次接着线程B打印一次如此循环下去。

    代码改造:

    public class MutexTest {
        public static void main(String[] args) {
            final Writer writer = new Writer();
            new Thread(new Runnable() {
                public void run() {
                    for (int i = 0; i < 10; i++) {
                        writer.sub(i + 1);
                    }
                }
            }).start();
    
            for (int i = 0; i < 10; i++) {
                writer.main(i + 1);
            }
        }
    }
    class Writer {
        boolean isSubThread = true;
        public synchronized void main(int num) {
            while (!isSubThread) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int i = 1; i <= 100; i++) {
                System.out.println("main thread sequece of " + i + ",loop of " + num);
            }
            isSubThread = false;
            this.notify();
        }
        public synchronized void sub(int num) {
            while (isSubThread) {
                try {
                    this.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            for (int i = 1; i <= 10; i++) {
                System.out.println("sub thread sequece of " + i + ",loop of " + num);
            }
            isSubThread = true;
            this.notify();
        }
    }

    执行结果:

  • 相关阅读:
    读《人人都是产品经理》
    前端值得看的博客
    git 常用命令 创建查看删除分支,创建查看删除tag等
    看《如何令选择变得更加容易》
    读【失控】——众愚成智
    html5 postMessage
    下拉滚动加载更多数据
    html select用法总结
    分布式系统事务一致性解决方案
    nginx简易教程
  • 原文地址:https://www.cnblogs.com/Laymen/p/5992987.html
Copyright © 2020-2023  润新知