背景:并发知识是一个程序员段位升级的体现,同样也是进入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. openstack学习(1)

    OpenStack项目结构 OpenStack架构 1. horizon以图形的方式管理所有的project,包括nova虚拟机的创建,neutron网络,cinder存储,glance镜像等:    ...

  2. ceph 常见问题百科全书---luminous安装部署篇

    1. 执行步骤:ceph-deploy new node        机器:centos 7.5   ceph  Luminous版本     源:阿里云 问题: Traceback (most r ...

  3. java的8种基础类型

    一.基础类型 Java 是一种强类型语言 . 这就意味着必须为每一个变量声明一种类型 : 在 Java 中,一共有 8种基本类型 ( primitive type ) , 其中有 4 种整型 . 2 ...

  4. eShopOnContainers 知多少[8]:Ordering microservice

    1. 引言 Ordering microservice(订单微服务)就是处理订单的了,它与前面讲到的几个微服务相比要复杂的多.主要涉及以下业务逻辑: 订单的创建.取消.支付.发货 库存的扣减 2. 架 ...

  5. 重学前端 --- Promise里的代码为什么比setTimeout先执行?

    首先通过一段代码进入讨论的主题 var r = new Promise(function(resolve, reject){ console.log("a"); resolve() ...

  6. layui选项卡同步问题

    下面这些代码是在有选项卡的情况下, 一个页面的状态修改时打开另一个选项卡, 另一个选项卡修改成功后,可以使你当前的选项卡状态实时更新 // 重载当前的页面的需要刷新的表格 table.reload(' ...

  7. DataPipeline联合Confluent Kafka Meetup上海站

    Confluent作为国际数据“流”处理技术领先者,提供实时数据处理解决方案,在市场上拥有大量企业客户,帮助企业轻松访问各类数据.DataPipeline作为国内首家原生支持Kafka解决方案的“iP ...

  8. Redis的知识点总结~Linux系统操作~

    Redis_启动后杂项基础 Redis一共16个数据库 SELECT[0~15] 来切换数据库 命令起效返回1 不起效返回0 或者nil 或者error 异常... DBSIZE 查询数据的数 KEY ...

  9. Windows Cluster 添加新节点--验证报错

    今天给既有Windows Cluster 添加节点时,验证总是不通过.报错信息为 防火墙未正确配置为故障转移群集.现将处理步骤汇总如下. 1.错误具体信息 报错的位置 --[验证警告] 的步骤中发现错 ...

  10. Windows Server 2016-命令行方式管理Windows服务

    Microsoft Windows 服务(过去称为 NT 服务)允许用户创建可在其自身的 Windows 会话中长时间运行的可执行应用程序. 这些服务可在计算机启动时自动启动,可以暂停和重启,并且不显 ...