Java 多线程中交替执行问题

Java 多线程中。两个线程交替执行,输出相应字母

可以通过Synchronized与ReentrantLock
ReentrantLock与synchronized关键字一样,属于互斥锁,synchronized中的锁是非公平的(公平锁是指多个线程等待同一个锁时,必须按照申请锁的时间顺序来依次获得锁),ReentrantLock默认情况下也是非公平的,但可以通过带布尔值的构造函数要求使用公平锁。线程通过ReentrantLock的lock()方法获得锁,用unlock()方法释放锁。

ReentrantLock和synchronized关键字的区别

ReentrantLock在等待锁时可以使用lockInterruptibly()方法选择中断, 改为处理其他事情,而synchronized关键字,线程需要一直等待下去。同样的,tryLock()方法可以设置超时时间,用于在超时时间内一直获取不到锁时进行中断。
ReentrantLock可以实现公平锁,而synchronized的锁是非公平的。
ReentrantLock拥有方便的方法用于获取正在等待锁的线程。
ReentrantLock可以同时绑定多个Condition对象,而synchronized中,锁对象的wait()和notify()或notifyAll()方法可以实现一个隐含的条件,如果要和多于一个条件关联时,只能再加一个额外的锁,而ReentrantLock只需要多次调用newCondition方法即可。
性能比较
在JDK1.6之前,ReentrantLock的性能要明显优于synchronized,但是JDK1.6中加入了很多针对锁的优化措施,synchronized和ReentrantLock的性能基本完全持平了。

ReentrantLock缺点
ReentrantLock的主要缺点是方法需要置于try-finally块中,另外,开发人员需要负责获取和释放锁,而开发人员常常忘记在finally中释放锁。

通过synchronized关键词

public class AlterThread {
    public static void main(String[] args) {
        AlterThread test = new AlterThread();

        Object lock = new Object();

        test.new Output(lock, "A").start();
        test.new Output(lock, "B").start();
    }

    class Output extends Thread {
        private Object lock;
        private String value;

        public Output(Object lock, String value) {
            this.lock = lock;
            this.value = value;
        }

        @Override
        public void run() {
            synchronized (lock) {
                while (true) {
                    try {
                        System.out.println(value);
                        lock.notifyAll();
                        lock.wait();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }
}

通过ReentrantLock

public class AlterThreadTest {
    private ReentrantLock lock = new ReentrantLock();
    Condition aCondition = lock.newCondition();
    Condition bCondition = lock.newCondition();

    public static void main(String[] args) {
        AlterThreadTest test = new AlterThreadTest();

        test.new AOutput().start();
        test.new BOutput().start();
    }

    class AOutput extends Thread {

        @Override
        public void run() {
            while (true) {
                try {
                    lock.lock();
                    System.out.println("A");

                    bCondition.signal();
                    aCondition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }

    class BOutput extends Thread {

        @Override
        public void run() {
            while (true) {
                try {
                    lock.lock();
                    System.out.println("B");
                    aCondition.signal();
                    bCondition.await();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                } finally {
                    lock.unlock();
                }
            }
        }
    }
}

代码源码
https://github.com/zhxhcoder/codeProj

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 线程安全 当多个线程访问一个对象时,如果不用考虑这些线程在运行时环境下的调度和交替执行,也不需要进行额外的同步,或...
    闽越布衣阅读 783评论 0 6
  • 一、进程和线程 进程 进程就是一个执行中的程序实例,每个进程都有自己独立的一块内存空间,一个进程中可以有多个线程。...
    阿敏其人阅读 2,625评论 0 13
  • Java8张图 11、字符串不变性 12、equals()方法、hashCode()方法的区别 13、...
    Miley_MOJIE阅读 3,731评论 0 11
  • 只为回家过个年,十万劳工挤车站。铁路运营偷着乐,人流涌动全是钱。
    简村小吹阅读 342评论 11 24
  • 心理咨询师舒蔓说,除了自信,其他几乎所有的“自拍达人”无非分为两类:1.释放一个“本我”;2.创造一个“自我”。隐...
    苏达Vinci阅读 311评论 0 5