并发编程系列小结(线程安全,synchronized,脏读,线程间的通信wait/notify,线程的三种实现方式Demo,可替代wait/notify的方法)
线程安全:
当多个线程访问某一个类(对象或方法)时,这个类始终都能表现出正确的行为,那么这个类(对象或方法就是线程安全的)
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的方法)的更多相关文章
- python并发编程之多进程1-----------互斥锁与进程间的通信
一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...
- python并发编程之多进程1--(互斥锁与进程间的通信)
一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...
- python并发编程之多进程1互斥锁与进程间的通信
一.互斥锁 进程之间数据隔离,但是共享一套文件系统,因而可以通过文件来实现进程直接的通信,但问题是必须自己加锁处理. 注意:加锁的目的是为了保证多个进程修改同一块数据时,同一时间只能有一个修改,即串行 ...
- java并发编程系列原理篇--JDK中的通信工具类Semaphore
前言 java多线程之间进行通信时,JDK主要提供了以下几种通信工具类.主要有Semaphore.CountDownLatch.CyclicBarrier.exchanger.Phaser这几个通讯类 ...
- [ 高并发]Java高并发编程系列第二篇--线程同步
高并发,听起来高大上的一个词汇,在身处于互联网潮的社会大趋势下,高并发赋予了更多的传奇色彩.首先,我们可以看到很多招聘中,会提到有高并发项目者优先.高并发,意味着,你的前雇主,有很大的业务层面的需求, ...
- Java并发编程系列-(7) Java线程安全
7. 线程安全 7.1 线程安全的定义 如果多线程下使用这个类,不过多线程如何使用和调度这个类,这个类总是表示出正确的行为,这个类就是线程安全的. 类的线程安全表现为: 操作的原子性 内存的可见性 不 ...
- 原创】Java并发编程系列2:线程概念与基础操作
[原创]Java并发编程系列2:线程概念与基础操作 伟大的理想只有经过忘我的斗争和牺牲才能胜利实现. 本篇为[Dali王的技术博客]Java并发编程系列第二篇,讲讲有关线程的那些事儿.主要内容是如下这 ...
- Java并发编程系列-(2) 线程的并发工具类
2.线程的并发工具类 2.1 Fork-Join JDK 7中引入了fork-join框架,专门来解决计算密集型的任务.可以将一个大任务,拆分成若干个小任务,如下图所示: Fork-Join框架利用了 ...
- Java并发编程系列-(6) Java线程池
6. 线程池 6.1 基本概念 在web开发中,服务器需要接受并处理请求,所以会为一个请求来分配一个线程来进行处理.如果每次请求都新创建一个线程的话实现起来非常简便,但是存在一个问题:如果并发的请求数 ...
随机推荐
- 原生js遍历每一个对象,给每一个对象添加onclick事件
<script type="text/javascript"> window.onload = function () { var imgs = document.im ...
- (4) go 运算符
1. (1) 整数相除,结果是小数,会舍去小数部分 (2) 使用自增自减时, ++ -- 必须单独一行 (3)只有后 a++,没有前 ++a 2. 3. 4. 5 6. 7. 8.
- ZOJ 3781 Paint the Grid Reloaded
枚举,$BFS$,连通块缩点. 可以枚举一开始染哪个位置,然后逐层往外染色,看最多需要多少操作次数,也就是算最短距离.连通块缩点之后可以保证是一个黑白相间的图,且每条边的费用均为$1$,$BFS$即可 ...
- 洛谷——P2299 Mzc和体委的争夺战
P2299 Mzc和体委的争夺战 题目背景 mzc与djn第四弹. 题目描述 mzc家很有钱(开玩笑),他家有n个男家丁(做过前三弹的都知道).但如此之多的男家丁吸引来了我们的体委(矮胖小伙),他要来 ...
- 洛谷——P1724 东风谷早苗
P1724 东风谷早苗 题目描述 在幻想乡,东风谷早苗是以高达控闻名的高中生宅巫女.某一天,早苗终于入手了最新款的钢达姆模型.作为最新的钢达姆,当然有了与以往不同的功能了,那就是它能够自动行走,厉害吧 ...
- 51nod 1052 (dp)
最大M子段和 N个整数组成的序列a[1],a[2],a[3],…,a[n],将这N个数划分为互不相交的M个子段,并且这M个子段的和是最大的.如果M >= N个数中正数的个数,那么输出所有正数的和 ...
- XPath语法和CSS选择器介绍
XPath语法 XPath 是一门在 XML 文档中查找信息的语言.XPath 可用来在 XML 文档中对元素和属性进行遍历.XPath 是 W3C XSLT 标准的主要元素,并且 XQuery 和 ...
- 在CentOS6或RHEL6恢复上ext4文件系统误删除的文件
首先说明: [root@CentOS6 ~]# rm -rf / //这条命令不可以执行 [root@CentOS6 ~]# rm -rf /* //这条命令可以执行,别去试 ext4文件系统上误删除 ...
- Electron:将前端应用打包成桌面应用
首先戳我下载安装对应版本的node.js. 安装完成后,打开命令行输入node -v以及npm -v查看对应版本.能够正常显示说明安装成功. 写一个最简单的hello world的nodejs应用.n ...
- bzoj 3373: [Usaco2004 Mar]Lying Livestock 说谎的牲畜
3373: [Usaco2004 Mar]Lying Livestock 说谎的牲畜 Description 兽群中总是有一些麻烦制造者.约翰知道他的N(1≤N≤100)头奶牛中有一头总是说谎,其他的 ...