背景:并发知识是一个程序员段位升级的体现,同样也是进入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的更多相关文章

  1. Java并发---concurrent包

    一.包的结构层次 其中包含了两个子包atomic和locks,另外字concurrent下的阻塞队列以及executor,这些就是concurrent包中的精华.而这些类的实现主要是依赖于volati ...

  2. 并行parallel和并发concurrent的区别

    http://stackoverflow.com/questions/1050222/concurrency-vs-parallelism-what-is-the-difference Concurr ...

  3. java 并发 concurrent Executor

    Excutor类 Executor 执行提交的对象Runnable任务. ExecutorService 一个Executor ,提供方法来管理终端和方法,可以产生Future为跟踪一个或多个异步任务 ...

  4. Java虚拟机6:内存溢出和内存泄露、并行和并发、Minor GC和Full GC、Client模式和Server模式的区别

    前言 之前的文章尤其是讲解GC的时候提到了很多的概念,比如内存溢出和内存泄露.并行与并发.Client模式和Server模式.Minor GC和Full GC,本文详细讲解下这些概念的区别. 内存溢出 ...

  5. iOS 处理多个网络请求的并发的情况

    如何处理多个网络请求的并发的情况 一.概念 1.并发 当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配 ...

  6. 并发concurrent---2

    背景:并发知识是一个程序员段位升级的体现,同样也是进入BAT的必经之路,有必要把并发知识重新梳理一遍. 并发concurrent: 使用ThreadLocal可以实现线程范围内共享变量,线程A写入的值 ...

  7. python多进程并发和多线程并发和协程

    为什么需要并发编程? 如果程序中包含I/O操作,程序会有很高的延迟,CPU会处于等待状态,这样会浪费系统资源,浪费时间 1.Python的并发编程分为多进程并发和多线程并发 多进程并发:运行多个独立的 ...

  8. java并发编程概念

    并发:当有多个线程在操作时,如果系统只有一个CPU,则它根本不可能真正同时进行一个以上的线程,它只能把CPU运行时间划分成若干个时间段,再将时间 段分配给各个线程执行,在一个时间段的线程代码运行时,其 ...

  9. 《C#并发编程经典实例》学习笔记-关于并发编程的几个误解

    误解一:并发就是多线程 实际上多线程只是并发编程的一种形式,在C#中还有很多更实用.更方便的并发编程技术,包括异步编程.并行编程.TPL 数据流.响应式编程等. 误解二:只有大型服务器程序才需要考虑并 ...

随机推荐

  1. python 小练习题做起来

    1# 有两个磁盘文件A和B,各存放一行字母,要求把这两个文件中的信息合并# (按字母顺序排列), 输出到一个新文件C中.with open('a') as f1: a=f1.read()with op ...

  2. Airtest 快速上手教程

    一.Airtest 简介: AirtestIDE 是一个跨平台的UI自动化测试编辑器,适用于游戏和App. 自动化脚本录制.一键回放.报告查看,轻而易举实现自动化测试流程 支持基于图像识别的 Airt ...

  3. spring JdbcTemplate 在itest 开源测试管理项目中的浅层(5个使用场景)封装

    导读: 主要从4个方面来阐述,1:背景:2:思路:3:代码实现:4:使用 一:封装背景, 在做项目的时候,用的JPA ,有些复杂查询,比如报表用原生的JdbcTemplate ,很不方便;传参也不方便 ...

  4. 国内开源社区巨作AspectCore-Framework入门

    前些天和张队(善友),lemon(浩洋),斌哥(项斌)等MVP大咖一块儿吃饭,大家聊到了lemon名下的AOP这个项目,我这小白听得一脸懵逼,后面回来做了一下功课,查了下资料,在lemon的Githu ...

  5. Redis - NoSQL数据库技术(一)

    NoSQL入门概述(一) 作者 : Stanley 罗昊 [转载请注明出处和署名,谢谢!] 什么是NoSQL NoSQL(NoSQL - Not Only SQL),意“不仅仅是SQL”: 泛指非关系 ...

  6. 一文快速了解MaxCompute

    很多刚初次接触MaxCompute的用户,面对繁多的产品文档内容以及社区文章,往往很难快速.全面了解MaxCompute产品全貌.同时,很多拥有大数据开发经验的开发者,也希望能够结合自身的背景知识,将 ...

  7. Mybatis插入数据返回主键ID

    <insert id="add" parameterType="com.dsa.core.base.model.ProductSync">      ...

  8. Web前端 css实现元素垂直居中的常用方法

    方法1:table-cell html结构: 1 2 3 <div class="box box1">         <span>垂直居中</spa ...

  9. salesforce初探

      Salesforce的商业模式? 从做CRM SAAS起家,可以理解为在线CRM,不需要硬件和服务器,输入用户名和密码就能登陆使用.2007年推出PaaS平台Force.com,可以说,它依托CR ...

  10. 001-为什么Java能这么流行

    本文首发于公众号:javaadu 典型回答 这种问题比较笼统,如果我遇到这个问题,我会从下面几个点阐述我的观点: Java通过JVM实现了"一次编写,到处运行"的特性,由JVM屏蔽 ...