并发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 数据流.响应式编程等. 误解二:只有大型服务器程序才需要考虑并 ...
随机推荐
- ActiveMQ详解
Apache ActiveMQ介绍 使用MQ的场景 ActiveMQ的安装 收发消息的简单实现 ActiveMQ内部实现 queue和topic 消息持久化 kahadb原理 最关键的6个配置 Apa ...
- 微服务(入门四):identityServer的简单使用(客户端授权)
IdentityServer简介(摘自Identity官网) IdentityServer是将符合规范的OpenID Connect和OAuth 2.0端点添加到任意ASP.NET核心应用程序的中间件 ...
- sau交流学习社区—vue总结:使用vue的computed属性实现监控变量变化,使用vue的watch属性监控变量变化从而实现其他业务
有时候遇到这么个需求,输入框为空的时候,请求一遍接口,如果输入框不为空的时候,需要点击搜索按钮请求接口. 同步sau交流学习社区:https://www.mwcxs.top/page/464.html ...
- 【原】使用less实现随机下雪动画
元旦在公司撸码,想起圣诞节的摇摇乐项目有段代码挺有意思的,借着空闲的时间把代码抽出来,沉淀下经验.冬天来了,设计师说摇摇乐的场景需要随机下落的雪花动画,第一时间就想到的方法是canvas比较好,项目非 ...
- 什么是TensorBoard?
前言 只有光头才能变强. 文本已收录至我的GitHub仓库,欢迎Star:https://github.com/ZhongFuCheng3y/3y 回顾前面: 从零开始学TensorFlow[01-搭 ...
- kubernetes实践之五:深入理解Service及内部DNS搭建
一.Service存在的意义: 防止Pod失联(服务发现) 定义一组Pod的访问策略(负载均衡) 支持ClusterIP,NodePort以及LoadBalancer三种类型 Service的底层实现 ...
- Oracle 中的SELECT 关键字(查询、检索)
1. SELECT 关键字用法: 检索单个列:select 列名 from 表名: 例:select ename from emp;检索多个列: select [列1,列2, ... ,列N] fro ...
- C# 操作Word页眉页脚——奇偶页/首页不同、不连续设置页码、复制页眉页脚、锁定页眉页脚、删除页眉页脚
前言 本文是对Word页眉页脚的操作方法的进一步的阐述.在“C# 添加Word页眉页脚.页码”一文中,介绍了添加简单页眉页脚的方法,该文中的方法可满足于大多数的页眉页脚添加要求,但是对于比较复杂一点的 ...
- 16 , CSS 边框与边界
1.CSS 中边框的使用 2.CSS 中边界的使用 16.1 CSS 中边框的使用 属性名称 属性值 说明 border-color 十六进制 可依序设置上,右,下,左线颜色 英文名称 border- ...
- 基于geoserver的REST服务完成mysql数据源动态发布
文章版权由作者李晓晖和博客园共有,若转载请于明显处标明出处:http://www.cnblogs.com/naaoveGIS/ 1. 背景 在之前的<简析GeoServer服务的内部文件组织以及 ...