zoukankan      html  css  js  c++  java
  • 线程间的互斥与通信

    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();
        }
    }

    执行结果:

  • 相关阅读:
    [mysql] 删除唯一约束unique
    onethink 路由规则无效问题解决
    mysql source 乱码
    NLPIR
    词性标记集--计算所汉语
    [thinkphp] 无限极分类
    UITableViewCell在非Nib及Cell重用下设置CellStyle
    UIViewController的初始化
    转:NSString / NSData / char* 类型之间的转换
    转:苹果Xcode帮助文档阅读指南
  • 原文地址:https://www.cnblogs.com/Laymen/p/5992987.html
Copyright © 2011-2022 走看看