并发concurrent---1
背景:并发知识是一个程序员段位升级的体现,同样也是进入BAT的必经之路,有必要把并发知识重新梳理一遍。
并发concurrent:
说到并发concurrent,肯定首先想到了线程,创建线程有两种方法:1、从Java.lang.Thread类派生一个新的线程类,重载它的run()方法;2、实现Runnalbe接口,重载Runnalbe接口中的run()方法;建议使用方法二创建线程,因为,如果是通过扩展 Thread类的方法来创建线程,那么这个自定义类就不能再去扩展其他的类,也就无法实现更加复杂的功能;而实现Runnable接口的方法来定义该类为线程类,这样就可以避免Java单继承所带来的局限性,也更符合面向对象编程的思想,最重要的就是使用实现Runnable接口的方式创建的线程可以处理同一资源,从而实现资源的共享。
创建线程的两种方法:
package www.concurent.test;
public class TraditionalThread { public static void main(String[] args) {
//Thread1:
Thread thread = new Thread() {
@Override
public void run() {
while(true) {
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread1: "+Thread.currentThread().getName());
}
}
};
thread.start(); //Thread2:
//Runnable变量是线程要运行的代码的宿主,更适合面向对象思想的线程方法
Thread thread2 = new Thread(new Runnable() {
@Override
public void run() {
while(true) {
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("thread2: "+Thread.currentThread().getName());
}
}
});
thread2.start();
}
}
线程和Timer定时器很类似,下面介绍了两种和线程相似的定时器写法:1、定时一天之后调用方法查询天气情况接口,然后每隔60秒后继续调用该方法;2、定时每天00:39:32调用查询天气情况接口,通过Hutool工具和Timer定时器调用HTTP天气状况接口的返回结果如下截图:(result2得到了天津的天气状况)
通过Hutool工具和Timer定时器调用HTTP天气状况接口:
import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import cn.hutool.http.HttpUtil; public class TraditionalTimerTest {
//时间间隔
private static final long PERIOD_DAY = * * * ;
//Timer 定时器
public static void main(String[] args) {
Calendar cl = Calendar.getInstance();
cl.set(Calendar.HOUR_OF_DAY, );
cl.set(Calendar.MINUTE, 3);
cl.set(Calendar.SECOND, );
Date date = cl.getTime();
Date dateNow = new Date();
//如果第一次执行定时任务的时间 小于 当前的时间
//此时要在 第一次执行定时任务的时间 加一天,以便此任务在下个时间点执行。如果不加一天,任务会立即执行。
if (date.before(dateNow)) {
Calendar clAdd = Calendar.getInstance();
clAdd.setTime(dateNow);
clAdd.add(Calendar.DAY_OF_MONTH, );
date = clAdd.getTime();
}
//Timer1:
new Timer().schedule(new TimerTask() {
@Override
public void run() {
System.out.println("hello");
//Hutool调用http接口
String result1 = HttpUtil.get("http://t.weather.sojson.com/api/weather/city/101030100");
System.out.println("result1: "+result1);
}
//一天之后调用方法查询天气情况接口,然后每隔60秒后继续调用该方法
},PERIOD_DAY , *);
//Timer2:
new Timer().schedule(new TimerTask() {
@Override
public void run() {
//Hutool调用http接口
String result2 = HttpUtil.get("http://t.weather.sojson.com/api/weather/city/101030100");
System.out.println("result2: " + result2);
}
//定时每天00:39:32调用查询天气情况接口
}, date , PERIOD_DAY);
} }
如果是单个线程调用都还ok,要是有多个线程同时调用那就会出现并发产生;比如有一个方法Output()是经过charAt(i)获取字符串i的字符并且打印再控制台,然后线程A和线程B同时调用Output()方法,此时就会出现线程不安全问题(如银行取钱和转账同时进行),也就是并发;执行结果发现,线程A为执行完毕线程B就开始执行了,为了能后保证当有一个线程来执行某个方法时,其他的线程不能进来执行该方法,实现排他性,可以通过synchronized和ReentrantLock来实现线程同步;二者其实区别不大,synchronized由于是底层JVM实现的互斥,因此效率会高一些,而ReentrantLock的功能则比synchronized更多,比如定时获取某个锁,多个等待条件等,另外synchronized 会让线程阻塞,ReentrantLock会让线程等待,但是从行为效果上来看是一样的;下面有个例子:并发结果如截图显示,理想状态是打印“huawei”或者“isoftstone”,但是由于并发打印出来诸如此类“ishuaweoftstoni”结果。
FYI:
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock; public class MyThreadSynchronized {
public static void main(String[] args) {
//要想调用内部类的对象,必须有外部类的实例对象
new MyThreadSynchronized().init(); // 外部类的实例对象
}
public void init() {
final Outputer outputer = new Outputer();
//thread1:
new Thread(new Runnable() {
@Override
public void run() {
while(!false) {
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output3("huawei");
}
}
}).start(); //thread2:
new Thread(new Runnable() {
@Override
public void run() {
while(!false) {
try {
Thread.sleep();
} catch (InterruptedException e) {
e.printStackTrace();
}
outputer.output("isoftstone");
}
}
}).start();
}
//当有一个线程来执行某个方法时,其他的线程不能进来执行该方法,排他性、独一无二;
//使用synchronized/lock同步,且线程用的同步锁是同一个同步对象,可用this互斥或方法.class
//synchronized由于是底层JVM实现的互斥,因此效率会高一些
//ReentrantLock的功能则比synchronized更多,比如定时获取某个锁,多个等待条件
//synchronized 会让线程阻塞,ReentrantLock会让线程等待,但是从行为效果上来看是一样的;
class Outputer{
//内部类 静态方法中不能new内部类的实例对象
//synchronized:
public synchronized void output(String name) {
for(int i = ; i<name.length(); i++) {
System.out.print(name.charAt(i));
}
System.out.println();// switch line
} //线程不安全
public void output3(String name) {
for(int i = ; i<name.length(); i++) {
System.out.print(name.charAt(i));
}
System.out.println();// switch line
} //lock:
public void ouputlock(String name) {
Lock lock = new ReentrantLock();
lock.lock(); // 上锁同步
try {
for (int i = ; i < name.length(); i++) {
System.out.print(name.charAt(i));
}
System.out.println();// switch line
} finally {
lock.unlock(); // 解锁
}
} } }
并发concurrent---1的更多相关文章
- Java并发---concurrent包
一.包的结构层次 其中包含了两个子包atomic和locks,另外字concurrent下的阻塞队列以及executor,这些就是concurrent包中的精华.而这些类的实现主要是依赖于volati ...
- 并行parallel和并发concurrent的区别
http://stackoverflow.com/questions/1050222/concurrency-vs-parallelism-what-is-the-difference Concurr ...
- java 并发 concurrent Executor
Excutor类 Executor 执行提交的对象Runnable任务. ExecutorService 一个Executor ,提供方法来管理终端和方法,可以产生Future为跟踪一个或多个异步任务 ...
- Java虚拟机6:内存溢出和内存泄露、并行和并发、Minor GC和Full GC、Client模式和Server模式的区别
前言 之前的文章尤其是讲解GC的时候提到了很多的概念,比如内存溢出和内存泄露.并行与并发.Client模式和Server模式.Minor GC和Full GC,本文详细讲解下这些概念的区别. 内存溢出 ...
- iOS 处理多个网络请求的并发的情况
如何处理多个网络请求的并发的情况 一.概念 1.并发 当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配 ...
- 并发concurrent---2
背景:并发知识是一个程序员段位升级的体现,同样也是进入BAT的必经之路,有必要把并发知识重新梳理一遍. 并发concurrent: 使用ThreadLocal可以实现线程范围内共享变量,线程A写入的值 ...
- python多进程并发和多线程并发和协程
为什么需要并发编程? 如果程序中包含I/O操作,程序会有很高的延迟,CPU会处于等待状态,这样会浪费系统资源,浪费时间 1.Python的并发编程分为多进程并发和多线程并发 多进程并发:运行多个独立的 ...
- java并发编程概念
并发:当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其 ...
- 《C#并发编程经典实例》学习笔记-关于并发编程的几个误解
误解一:并发就是多线程 实际上多线程只是并发编程的一种形式,在C#中还有很多更实用.更方便的并发编程技术,包括异步编程.并行编程.TPL 数据流.响应式编程等. 误解二:只有大型服务器程序才需要考虑并 ...
随机推荐
- H5单张、多张图片上传
前言 今天我们聊一聊图片上传,单张Or多张 ,如今,各大图片上传插件数不胜数,例如:Jquery的 verupload.js,jQuery File Upload.Uploadify.jQuery.f ...
- FreeSql 新的八大骚功能,.NETCore 你必须晓得的 ORM
前言 FreeSql 目前版本号 0.5.5,预计明年元旦发布 1.0.0,切莫小看了版本号,目前单元测试方法1350+,并且每个方法内的涵盖面又比较广(不信的话见下图),每一次版本发布都作了较多的测 ...
- go语言调度器源代码情景分析之六:go汇编语言
go语言runtime(包括调度器)源代码中有部分代码是用汇编语言编写的,不过这些汇编代码并非针对特定体系结构的汇编代码,而是go语言引入的一种伪汇编,它同样也需要经过汇编器转换成机器指令才能被CPU ...
- 网络协议 22 - RPC 协议(下)- 二进制类 RPC 协议
前面我们认识了两个常用文本类的 RPC 协议,对于陌生人之间的沟通,用 NBA.CBA 这样的缩略语,会使得协议约定非常不方便. 在讲 CDN 和 DNS 的时候,我们讲过接入层的设计 ...
- asp.net core系列 55 IS4结合Identity密码保护API
一.概述 OAuth 2.资源所有者密码授权允许客户端(Client项目)向令牌服务(IdentityServer项目)发送用户名和密码,并获取代表该用户的访问令牌.本篇将IS4结合asp.net c ...
- 理解 KMP 算法
KMP(The Knuth-Morris-Pratt Algorithm)算法用于字符串匹配,从字符串中找出给定的子字符串.但它并不是很好理解和掌握.而理解它概念中的部分匹配表,是理解 KMP 算法的 ...
- Thymeleaf【快速入门】
前言:突然发现自己给自己埋了一个大坑,毕设好难..每一个小点拎出来都能当一个小题目(手动摆手..),没办法自己选的含着泪也要把坑填完..先一点一点把需要补充的知识学完吧.. Thymeleaf介绍 稍 ...
- Spring Boot入门(四):开发Web Api接口常用注解总结
本系列博客记录自己学习Spring Boot的历程,如帮助到你,不胜荣幸,如有错误,欢迎指正! 在程序员的日常工作中,Web开发应该是占比很重的一部分,至少我工作以来,开发的系统基本都是Web端访问的 ...
- Java开发笔记(八十九)缓存字节I/O流
文件输出流FileOutputStream跟FileWriter同样有个毛病,每次调用write方法都会直接写到磁盘,使得频繁的写操作性能极其低下.正如FileWriter搭上了缓存兄弟Buffere ...
- 高通QCC3026蓝牙音频芯片处理器介绍
QCC3026是一款基于超低功耗架构的入门级闪存可编程蓝牙音频SoC,专为紧凑型功能优化的Qualcomm TrueWireless耳塞而设计.QCC3026旨在为我们的客户提供有助于缩短开发时间并具 ...