当前位置:首页 > 开发语言 > 正文

java如何创建多线程?java中redis的面试题

java如何创建多线程?java中redis的面试题

大家好,关于java如何创建多线程很多朋友都还不太明白,今天小编就来为大家分享关于java中redis的面试题的知识,希望对各位有所帮助!在java web当中,ser...

大家好,关于java如何创建多线程很多朋友都还不太明白,今天小编就来为大家分享关于java中redis的面试题的知识,希望对各位有所帮助!

在java web当中,servlet在运行阶段,针对每个客户端的请求,都会创建一个线程,该线程调用servlet的实例

谢邀。

处理http请求的线程由JAVAWEBServer来管理。比如tomcat,jetty等。通常的作法是维护一个线程池,所有请求的执行都由这个线程池中的线程来完成,如果请求超过处理能力,就会发生等待甚至崩溃的情况,因此根据业务的访问量合理的设置线程池大小是非常重要的。

以tomcat为例,下面的源代码是tomcat处理http请求初始化的代码。可以从源代码中看出,tomcat会初始化一个ThreadPoolExecutor实例,而其中的参数可以在tomcat配置文件中进行配置。

希望可以解答题主的疑问。

Java:关于多线程与多核,如何将多核都利用上呢

你自己写个多线程的程序跑起来,把任务管理器打开,打开“性能”选项卡,观察你就发现了,其实不管你你的是4核,8核,1024核,基本都是在一个格子里有动作的,跟理论上几个线程就在几个核里跑不一致的,操作系统自身的设计导致的。核虽然多,县城虽然多,但是还没有真正设计成几个线程就在几个核里跑的算法模式。至于怎么都利用上不是你说了算,os说了算。别想太多。

如何使用java多线程处理http请求,求思路

先说长连接吧,如果TCP协议的话长连接可以通过心跳包来实现。2、推送的话,这个可以弄一个定时器,来控制线程,推送发送完毕,线程stop()。

python中的多线程和JAVA中的多线程有什么区别吗

python是支持多线程的,但是python里的多线程是单cpu意义上的多线程,它和多cpu上的多线程有着本质的区别,这是因为python存在一个叫GlobalInterpreterLock(GIL)全局解释器锁。

在解释器解释执行任何Python代码时,都需要先获得这把锁,也就是说在同一时刻内,只有一条线程可以在CPU中运行。

但是python的多线程并不是毫无用处的。当遇到I/O操作时会释放这把GIL锁,所以如果程序是一个IO密集型的程序,一个线程处在IO等待的时候另一个线程便可以取得锁并在CPU中运行,这时就发挥了多线程的作用。

但如果是纯计算的程序,没有I/O操作,那么只有取得GIL锁的线程可以在CPU中运行,其它的线程都处于等待状态,等待持有GIL锁的线程的释放锁,也就相当于单线程在跑(而且上下文切换也会有所开销)。

Java方面,其提供了并发机制:一个进程中可以并发多个线程,每条线程并行执行不同的任务。因为线程运行于多核CPU上,各线程可分布于CPU的各个核心,所以可以让程序实现真正的并发。

以上就是python和java多线程的区别,希望我的回答对你有所帮助。

线程池队列大小设置

一、ThreadPoolExecutor的重要参数

corePoolSize:核心线程数,核心线程会一直存活,及时没有任务需要执行,当线程数小于核心线程数时,即使有线程空闲,线程池也会优先创建新线程处理,设置allowCoreThreadTimeout=true(默认false)时,核心线程会超时关闭

queueCapacity:任务队列容量(阻塞队列)

当核心线程数达到最大时,新任务会放在队列中排队等待执行

maxPoolSize:最大线程数

当线程数>=corePoolSize,且任务队列已满时。线程池会创建新线程来处理任务

当线程数=maxPoolSize,且任务队列已满时,线程池会拒绝处理任务而抛出异常

keepAliveTime:线程空闲时间

当线程空闲时间达到keepAliveTime时,线程会退出,直到线程数量=corePoolSize

如果allowCoreThreadTimeout=true,则会直到线程数量=0

allowCoreThreadTimeout:允许核心线程超时

rejectedExecutionHandler:任务拒绝处理器

两种情况会拒绝处理任务:

当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务

当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务

线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常

ThreadPoolExecutor类有几个内部实现类来处理这类情况:

AbortPolicy丢弃任务,抛运行时异常

CallerRunsPolicy执行任务

DiscardPolicy忽视,什么都不会发生

DiscardOldestPolicy从队列中踢出最先进入队列(最后一个执行)的任务

实现RejectedExecutionHandler接口,可自定义处理器

二、ThreadPoolExecutor执行顺序

线程池按以下行为执行任务

(1)当线程数小于核心线程数时,创建线程。

(2)当线程数大于等于核心线程数,且任务队列未满时,将任务放入任务队列。

(3)当线程数大于等于核心线程数,且任务队列已满

1)若线程数小于最大线程数,创建线程

2)若线程数等于最大线程数,抛出异常,拒绝任务

三、如何设置参数

默认值

corePoolSize=1

queueCapacity=Integer.MAX_VALUE

maxPoolSize=Integer.MAX_VALUE

keepAliveTime=60s

allowCoreThreadTimeout=false

rejectedExecutionHandler=AbortPolicy()

如何来设置

需要根据几个值来决定

tasks:每秒的任务数,假设为500~1000

taskcost:每个任务花费时间,假设为0.1s

responsetime:系统允许容忍的最大响应时间,假设为1s

做几个计算

corePoolSize=每秒需要多少个线程处理?

threadcount=tasks/(1/taskcost)=tasks*taskcout=(500~1000)*0.1=50~100个线程。corePoolSize设置应该大于50

根据8020原则,如果80%的每秒任务数小于800,那么corePoolSize设置为80即可

queueCapacity=(coreSizePool/taskcost)*responsetime

计算可得queueCapacity=80/0.1*1=80。意思是队列里的线程可以等待1s,超过了的需要新开线程来执行

切记不能设置为Integer.MAX_VALUE,这样队列会很大,线程数只会保持在corePoolSize大小,当任务陡增时,不能新开线程来执行,响应时间会随之陡增。

maxPoolSize=(max(tasks)-queueCapacity)/(1/taskcost)

计算可得maxPoolSize=(1000-80)/10=92

(最大任务数-队列容量)/每个线程每秒处理能力=最大线程数

rejectedExecutionHandler:根据具体情况来决定,任务不重要可丢弃,任务重要则要利用一些缓冲机制来处理

keepAliveTime和allowCoreThreadTimeout采用默认通常能满足

以上都是理想值,实际情况下要根据机器性能来决定。如果在未达到最大线程数的情况机器cpuload已经满了,则需要通过升级硬件和优化代码,降低taskcost来处理。

多线程的实现方法,同步有几种方法

一、java允许多线程并发控制,当多个线程同时操作一个可共享的资源变量时(如数据的增删改查),将会导致数据不准确,相互之间产生冲突,因此加入同步锁以避免在该线程没有完成操作之前,被其他线程的调用,从而保证了该变量的唯一性和准确性。

二、实现方法:

1、同步方法即有synchronized关键字修饰的方法。由于java的每个对象都有一个内置锁,当用此关键字修饰方法时,内置锁会保护整个方法。在调用该方法前,需要获得内置锁,否则就处于阻塞状态。代码如:publicsynchronizedvoidsave(){}123注:synchronized关键字也可以修饰静态方法,此时如果调用该静态方法,将会锁住整个类

2、同步代码块即有synchronized关键字修饰的语句块。被该关键字修饰的语句块会自动被加上内置锁,从而实现同步。

3、使用特殊域变量(volatile)实现线程同步

1)volatile关键字为域变量的访问提供了一种免锁机制;

2)使用volatile修饰域相当于告诉虚拟机该域可能会被其他线程更新;

3)因此每次使用该域就要重新计算,而不是使用寄存器中的值;

4)volatile不会提供任何原子操作,它也不能用来修饰final类型的变量;

4、使用重入锁实现线程同步在JavaSE5.0中新增了一个java.util.concurrent包来支持同步。ReentrantLock类是可重入、互斥、实现了Lock接口的锁,它与使用synchronized方法和快具有相同的基本行为和语义,并且扩展了其能力

5、使用局部变量实现线程同步如果使用ThreadLocal管理变量,则每一个使用该变量的线程都获得该变量的副本,副本之间相互独立,这样每一个线程都可以随意修改自己的变量副本,而不会对其他线程产生影响。

如果你还想了解更多这方面的信息,记得收藏关注本站。

最新文章