Skip to content

shnehna/multiThreadDemo

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

9 Commits
 
 
 
 

Repository files navigation

线程创建的三个方法: 1、将类声明为Thread的子类。该子类应重写Thread类的run方法。接下来可以分配并启动
该子类的实例。例如,计算大于某一规定值的质数的线程可以写成:
class PrimeThread extends Thread {
long minPrime;
PrimeThread(long minPrime){
this.minPrime = minPrime;
}
public void run(){
// compute primes larger than minPrime
...
}
}
然后,下列代码会创建并启动一个线程:
PrimeThread p = new PrimeThread(143);
p.start();
2、另一种方法是声明实现Runnable接口的类。该类然后实现run方法。然后可以分配该类
的实例,再创建Thread时作为一个参数来传递并启动。采用这种风格的同一个例子如下所示:
class PrimeRun implements Runnable {
long minPrime;
PrimeRun(long minPrime) {
this.minPrime = minPrime;
}
public void run() {
// compute primes larger than minPrime
...
}
}
然后下列代码会创建并启动一个线程:
PrimeRun p = new PrimeRun(143);
new Thread(p).start();
#Thread.currentThread().getName(); 本类线程返回名字
#实现方式的好处 实现了解耦 使得线程和线程任务得到了分离 还有就是资源共享
而继承时资源独享
#运行方法main()的线程默认就是"main"
#而新建线程名字默认"Thread-0"、"Thread-1"以此类推
3、实现Callable接口方法call()
##################################################################
线程池
1、原理 ArrayList Thread t = array.remove(0); add(t);
2、JDK5后自带线程池
Executors:线程池创建工厂类 newFixedThreadPool(int nThreads)
##################################################################
run()方法两个弊端: 无法抛出异常 返回值为void
所以有个类Callable --> V call() throws Exception 用法和Runnable一样
##################################################################
线程安全问题
当一个线程进入共享数据操作的时候,无论是否休眠,其他线程只能等待
使用同步技术 公式:
synchronized(任意对象){
线程要操作的共享数据(是一个整体,不一定是某个数据,是run方法中操作共享数据的整体)
}
即同步代码块
线程池内的线程数的大小相关的概念有两个,一个是核心池大小,还有最大池大小。
如果当前的线程个数比核心池个数小,当任务到来,会优先创建一个新的线程并执行任务。
当已经到达核心池大小,则把任务放入队列,为了资源不被耗尽,队列的最大容量可能也是有上限的,
如果达到队列上限则考虑继续创建新线程执行任务,如果此刻线程的个数已经到达最大池上限,则考虑把任务丢弃。
在 java.util.concurrent 包中,提供了 ThreadPoolExecutor 的实现。
public ThreadPoolExecutor(int corePoolSize,int maximumPoolSize,long keepAliveTime,TimeUnit unit,BlockingQueue workQueue,
ThreadFactory threadFactory,RejectedExecutionHandler handler) { }
corePoolSize- 核心池大小,既然如前原理部分所述。需要注意的是在初创建线程池时线程不会立即启动,
直到有任务提交才开始启动线程并逐渐时线程数目达到corePoolSize。若想一开始就创建所有核心线程需调用prestartAllCoreThreads方法。
maximumPoolSize-池中允许的最大线程数。需要注意的是当核心线程满且阻塞队列也满时才会判断当前线程数是否小于最大线程数,并决定是否创建新线程。
keepAliveTime - 当线程数大于核心时,多于的空闲线程最多存活时间
unit - keepAliveTime 参数的时间单位。
workQueue - 当线程数目超过核心线程数时用于保存任务的队列。主要有3种类型的BlockingQueue可供选择:无界队列,有界队列和同步移交。将在下文中详细阐述。从参数中可以看到,此队列仅保存实现Runnable接口的任务。 别看这个参数位置很靠后,但是真的很重要,因为楼主的坑就因这个参数而起,这些细节有必要仔细了解清楚。
threadFactory - 执行程序创建新线程时使用的工厂。
handler - 阻塞队列已满且线程数达到最大值时所采取的饱和策略。java默认提供了4种饱和策略的实现方式:中止、抛弃、抛弃最旧的、调用者运行。将在下文中详细阐述。
...详见:https://zhuanlan.zhihu.com/p/32867181

About

多线程学习

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages