线程安全:

当多个线程访问某一个类(对象或方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法就是线程安全的)

synchronized:

可以在任意对象或方法上加锁,而加锁的这段代码称为“互斥区”或“临界区”

多个线程多个锁:

多个线程都有自己对应的锁

脏读:

在我们对一个对象的方法或对象加锁时,需要考虑业务的整体性,即为setValue/getValue方法同时加锁synchronized同步关键字,保证业务的原子性,不然会出现业务错误(也从侧面保证了数据的一致性)

线程间的通信:

使用notify/wait方法实现线程间的通信(注意这两个方法都是object类的方法)

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

wait方法释放锁,notify方法不释放锁

CountDownLatch与锁无关

线程的三种实现方式Demo

 package com.jonychen.test;

 import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask; /**
* 线程的三种实现方式
*/
public class TestDemo { public static void main(String[] args){
/**
* 第一种方式:继承Thread类重写run()方法
*/
Thread thread=new ThreadDemo();
thread.start(); /**
* 第二种方式:实现Runnable接口重写run()方法
*/
RunnableDemo runnableDemo=new RunnableDemo();
Thread thread1=new Thread(runnableDemo);
thread1.start();
try {
thread1.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
} /**
* 第三种方式:实现Callable接口重写call()方法
*/
CallableDemo callableDemo =new CallableDemo();
FutureTask<Integer> futureTask=new FutureTask<Integer>(callableDemo);
Thread thread2=new Thread(futureTask);
thread2.start();
try {
System.out.println("返回的参数为:"+futureTask.get());
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
} /**
* 第一种方式:继承Thread类重写run()方法
*/
class ThreadDemo extends Thread{
@Override
public void run() {
System.out.println("我是继承Thread类实现线程的一种方式!");
}
} /**
* 第二种方式:实现Runnable接口重写run()方法
*/
class RunnableDemo implements Runnable{
@Override
public void run() {
System.out.println("我是实现Runnable接口实现线程的一种方式");
}
} /**
* 第三种方式:实现Callable接口重写call()方法
*/
class CallableDemo implements Callable<Integer>{ @Override
public Integer call(){
return 666666;
}
}

输出截图:

可替代wait/notify的方法

 package com.jonychen.test;

 import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; /**
*java.util.concurrent 类库中提供了 Condition 类来实现线程之间的协调,可以在 Condition 上调用 await() 方法使线程等待,
* 其它线程调用 signal() 或 signalAll() 方法唤醒等待的线程。
* 相比于 wait() 这种等待方式,await() 可以指定等待的条件,因此更加灵活。
*
* 使用 Lock 来获取一个 Condition 对象。
*/
public class ConcurrentDemo { private Lock lock=new ReentrantLock();
private Condition condition=lock.newCondition(); public void before(){
lock.lock();
try {
System.out.println("before");
condition.signalAll();
} finally {
lock.unlock();
}
} public void after(){
lock.lock();
try {
condition.await();
System.out.println("after");
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
lock.unlock();
} } public static void main(String[] args){ ExecutorService executorService =Executors.newCachedThreadPool();
ConcurrentDemo concurrentDemo=new ConcurrentDemo();
executorService.execute(()->concurrentDemo.after());
executorService.execute(()->concurrentDemo.before());
} }

并发编程系列小结(线程安全,synchronized,脏读,线程间的通信wait/notify,线程的三种实现方式Demo,可替代wait/notify的方法)的更多相关文章

  1. python并发编程之多进程1-----------互斥锁与进程间的通信

    一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...

  2. python并发编程之多进程1--(互斥锁与进程间的通信)

    一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...

  3. python并发编程之多进程1互斥锁与进程间的通信

    一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...

  4. java并发编程系列原理篇--JDK中的通信工具类Semaphore

    前言 java多线程之间进行通信时,JDK主要提供了以下几种通信工具类.主要有Semaphore.CountDownLatch.CyclicBarrier.exchanger.Phaser这几个通讯类 ...

  5. [ 高并发]Java高并发编程系列第二篇--线程同步

    高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...

  6. Java并发编程系列-(7) Java线程安全

    7. 线程安全 7.1 线程安全的定义 如果多线程下使用这个类,不过多线程如何使用和调度这个类,这个类总是表示出正确的行为,这个类就是线程安全的. 类的线程安全表现为: 操作的原子性 内存的可见性 不 ...

  7. 原创】Java并发编程系列2:线程概念与基础操作

    [原创]Java并发编程系列2:线程概念与基础操作 伟大的理想只有经过忘我的斗争和牺牲才能胜利实现. 本篇为[Dali王的技术博客]Java并发编程系列第二篇,讲讲有关线程的那些事儿.主要内容是如下这 ...

  8. Java并发编程系列-(2) 线程的并发工具类

    2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ...

  9. Java并发编程系列-(6) Java线程池

    6. 线程池 6.1 基本概念 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:如果并发的请求数 ...

随机推荐

  1. Windows 上面优秀的工具软件推荐

    Windows 上面优秀的工具软件推荐 一.下载软件 1.速盘 - 度盘神器 简介: 使百度网盘保持全速下载免受限速困扰! 下载: speedpan 2.http下载工具 百度网盘破解下载器:prox ...

  2. PHP 边执行边输出

    <?php for ($i = 1; $i <= 5; $i++) { print "#$i 完毕<hr>"; sleep(1); print str_pa ...

  3. vmware漏洞之三——Vmware虚拟机逃逸漏洞(CVE-2017-4901)Exploit代码分析与利用

    本文简单分析了代码的结构.有助于理解. 转:http://www.freebuf.com/news/141442.html 0×01 事件分析 2017年7月19 unamer在其github上发布了 ...

  4. php过滤表单输入的emoji表情

    1.过滤emoji表情的原因 在我们的项目开发中,emoji表情是个麻烦的东西,即使我们可以能存储,也不一定能完美显示,因为它的更新速度很快:在iOS以外的平台上,例如PC或者android.如果你需 ...

  5. 洛谷P2587 [ZJOI2008] 泡泡堂

    题目传送门 分析:一道策略游戏题,要求最大期望得分和最小期望得分.首先分析最大,很显然是可以用一种类似于田忌赛马的思维来做,将两队的实力按照从大到小(其实从小到大也可以)排序,然后就按照顺序比较,可能 ...

  6. SGU167 I-country

    嗯以前在某个DP专题了发过这道题,但是当时没码代码,现在重发一篇题解 思考阶段如何划分:由已经处理的行数向下扩展,但是仅有行数我们无法描述状态空间那我们再加入已经选过的格子数,这样我们似乎可以确定我们 ...

  7. 洛谷——P1165 日志分析

    P1165 日志分析 题目描述 M 海运公司最近要对旗下仓库的货物进出情况进行统计.目前他们所拥有的唯一记录就是一个记录集装箱进出情况的日志.该日志记录了两类操作:第一类操作为集装箱入库操作,以及该次 ...

  8. 【数据结构】 最小生成树(四)——利用kruskal算法搞定例题×3+变形+一道大水题

    在这一专辑(最小生成树)中的上一期讲到了prim算法,但是prim算法比较难懂,为了避免看不懂,就先用kruskal算法写题吧,下面将会将三道例题,加一道变形,以及一道大水题,水到不用高级数据结构,建 ...

  9. python正则表达式中的分组 group

    维基百科:http://wiki.ubuntu.org.cn/Python%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F%E6%93%8D%E4%BD%9C ...

  10. 【后缀自动机】【拓扑排序】【动态规划】hihocoder1457 后缀自动机四·重复旋律7

    解题方法提示 小Hi:我们已经学习了后缀自动机,今天我们再来看这道有意思的题. 小Ho:好!这道题目让我们求的是若干的数字串所有不同子串的和. 小Hi:你能不能结合后缀自动机的性质来思考如何解决本题? ...