文档章节

线程(三)

 幸福快乐的小码农
发布于 2016/10/13 18:31
字数 435
阅读 1
收藏 0

一、线程间的通信

1、wait,notify

两个要结合使用,必须放在synchronized代码块或方法中,采用对象锁进行wait,notify

public class WaitNotifyTest {

    private volatile List<String> list = new ArrayList<String>();

    public void add() {
        list.add("1");
    }

    public int size() {
        return list.size();
    }

    public static void main(String[] args) {
        final Object object = new Object();
        final WaitNotifyTest test = new WaitNotifyTest();

        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                synchronized (object) {
                    System.out.println(Thread.currentThread().getName());
                    for (int i=0; i<10; i++) {
                        test.add();
                        if (test.size() == 5) {
                            object.notify();
                            System.out.println("唤醒t2线程");
                        }
                    }
                }
            }
        }, "t1");

        Thread thread2 = new Thread(new Runnable() {
            public void run() {
                synchronized (object) {
                    if (test.size() != 5) {
                        try {
                            System.out.println("---开始等待");
                            object.wait();
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                    }
                    System.out.println("---" + Thread.currentThread().getName());
                }
            }
        }, "t2");

        thread2.start();
        thread1.start();
    }

我先启动thread2线程,他先拿到锁,然后到逻辑,发现条件不满足,调用锁wait()释放锁,开始等待,然后thread1拿到锁之后,开始添加元素,到条件满足,调用锁的notify()去唤醒thread2,但是thread1不会释放自己锁,两个线程还存在竞争拿锁。

使用:wait,notify必须配合synchronized关键字使用

wait()会释放锁,notify()不会释放锁

public class QuenueTest {

    // 往一个集合中添加元素,take get
    public static volatile List<String> quene = new ArrayList<String>();

    public volatile int MAX_NUMBER = 5;

    public volatile int MIN_NUMBER = 0;

    public static AtomicInteger size = new AtomicInteger(5);

    Object lock = new Object();

    public void put(String string) {
        synchronized (lock) {
            while (size.get() == MAX_NUMBER) {
                try {
                    System.out.println("等待添加");
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            quene.add(string);
            size.incrementAndGet();
            lock.notify();
            System.out.println("--添加");
        }
    }

    public String take() {
        synchronized (lock) {
            while (size.get() == MIN_NUMBER) {
                try {
                    System.out.println("等待取出");
                    lock.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            String string = quene.remove(0);
            size.decrementAndGet();
            lock.notify();
            System.out.println("--取出");
            return string;
        }
    }

    public static void main(String[] args) {
        quene.add("1");
        quene.add("2");
        quene.add("3");
        quene.add("4");
        quene.add("5");


        final QuenueTest test = new QuenueTest();
        Thread thread = new Thread(new Runnable() {
            public void run() {
                test.put("6");
                test.put("7");
            }
        });

        thread.start();

        try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        Thread thread1 = new Thread(new Runnable() {
            public void run() {
                test.take();
                test.take();
            }
        });

        thread1.start();
    }

}

通过wait(),notify()模拟一个队列,设置最大、最小值,put,take的判断

2、ThreadLocal

 

 

© 著作权归作者所有

上一篇: 线程(四)
下一篇: 线程(二)
粉丝 0
博文 12
码字总数 5501
作品 0
闸北
私信 提问
多线程---线程的创建

一、定义线程 1、继承java.lang.Thread类。 此类中有个run()方法,应该注意其用法: public void run() 如果该线程是使用独立的 Runnable 运行对象构造的,则调用该 Runnable 对象的 run 方法...

董家二少
2016/01/13
36
0
Java线程:创建与启动

本文出自 “熔 岩” 博客,请务必保留此出处http://lavasoft.blog.51cto.com/62575/99151 一、定义线程 1、扩展java.lang.Thread类。 此类中有个run()方法,应该注意其用法: public void ru...

beibugulf
2016/11/18
1
0
Java 官方计数器 CountdownLatch

一个线程(或者多个),等待另外N个线程完成某个事情之后才能执行。是并发包中提供的一个可用于控制多个线程同时开始某个动作的类,其采用的方法为减少计数的方式,当计数减至零时位于latch.A...

燊在锦官城_
2018/08/18
0
0
join(long)与sleep(long)的区别

1.join(long)方法的源码 首先看join()源码: public final void join() throws InterruptedException {join(0); } 从源码中可以看出,join()直接调用了join(long)方法,join(long)源码如下:...

LoveOne
2015/12/14
464
0
Spring线程池ThreadPoolTaskExecutor

一、 ThreadPoolTaskExecutor 配置

ciyo_yang
2017/06/25
0
0

没有更多内容

加载失败,请刷新页面

加载更多

聊聊Elasticsearch的MonitorService

序 本文主要研究一下Elasticsearch的MonitorService MonitorService elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/monitor/MonitorService.java public class MonitorServic......

go4it
31分钟前
1
0
二、Docker

1、Docker - The TLDR(Too Long,Don't Read,Linxu 终端工具 ) Docker是在Linux和Windows上运行的软件。它创建、管理和编排容器。该软件以开源方式开发,在Github上作为Moby开源项目的一部分。...

倪伟伟
44分钟前
2
0
Python猫荐书系列之七:Python入门书籍有哪些?

本文原创并首发于公众号【Python猫】,未经授权,请勿转载。 原文地址:https://mp.weixin.qq.com/s/ArN-6mLPzPT8Zoq0Na_tsg 最近,猫哥的 Python 技术学习群里进来了几位比较特殊的同学:一...

豌豆花下猫
今天
5
0
Guava RateLimiter限流源码解析和实例应用

在开发高并发系统时有三把利器用来保护系统:缓存、降级和限流 缓存 缓存的目的是提升系统访问速度和增大系统处理容量 降级 降级是当服务出现问题或者影响到核心流程时,需要暂时屏蔽掉,待高...

算法之名
今天
13
0
国产达梦数据库与MySQL的区别

背景 由于项目上的需要,把项目实现国产化,把底层的MySQL数据库替换为国产的达梦数据库,花了一周的时间研究了国产的数据库-达梦数据库,它和MySQL有一定的区别,SQL的写法也有一些区别。 ...

TSMYK
今天
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部