浅析java多线程
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了浅析java多线程相关的知识,希望对你有一定的参考价值。
.一、概述:
从c开始,任何一门语言的默认执行顺序都是按照一条路走到黑的方式。
但是,当我们需要同时进行多项任务的时候该怎么办呢?这时我们可以将一个任务拆分成多个小任务同时处理(深层一点讲,就是虽然我单线程也能够做的到,但是cpu没有最高效率的利用,时间也没有高效的利用)。
所以:多线程解决的是并发的问题,目的是使任务执行效率更高,实现前提是“阻塞”。它们看上去时同时在执行的,但实际上只是分时间片试用cpu而已。
二、java任务:
作为一只Red_Ant,我才不关心Black_Ant搬过来的食物建筑的巢穴是怎么来的,因此java底层的多线程机制是如何执行的,这里就交给Black_Ant了。
java任务就是:实现Runnable接口类定义一个类。
那就简单了,就是说平常写的功能、方法、变量只要实现Runnable接口,把该任务实现的代码写到run方法中或者run方法调用就OK了。
举例:
package com.css.java.learning.action;
public class Task1 implements Runnable {
protected int countDown = 10;
public Task1(int countDown){
this.countDown = countDown;
}
public String mhtao(){
return "论10斤,红心猕猴桃可以吃几天?";
}
@Override
public void run() {
while(countDown-->0){
System.err.println(mhtao());
/**
* Java线程中的Thread.yield( )方法,译为线程让步,它能让当前线程由“运行状态”进入到“就绪状态”。
* 顾名思义,就是说当一个线程使用了这个方法之后,它就会把自己CPU执行的时间让掉。
* 然后,自己和其他线程一样。依据cup的执行概率来执行自己或其他线程
* 用Red_Ant的话来讲就是:大家依次排队挤公交,轮到这货了。
* 这货没有上车,而是讲了一句话:“大家一块儿挤啊,谁上去算谁的座位”。
* 于是轮流事件就变成了概率事件,个子大,有力气的可能概率大一点,后面的也有概率,不过小一点。
*/
Thread.yield();
}
}
}
定义了任务,此时并不涉及多线程,所以,任务本身就是一个类,它的对象我们可以在任意地方调用。
三、java线程:
java的线程是用来驱动任务执行的,也就是说你得把任务挂载到一个线程上,这样该线程才能驱动你定义的任务来执行。
①定义:
线程Thread自身并不执行任何操作,它只是用来被多线程机制调用,并驱动赋予它的任务。
声明线程并将任务附着到该线程上:
Thread t = new Thread(new Task1(5));
这样,任务就附着给了线程,下面就是让线程启动,只需要如下的调用:
t.start();
至此,线程声明ok。
②举例:
package com.css.java.learning.action;
public class Thread1 {
public static void main(String[] args) {
Thread t = new Thread(new Task1(5));
t.start();
System.err.println("线程任务已被java调用!");
}
}
可以看出,java调用线程之后。立马返回到了主程序上,然后再利用java的多线程机制,进行任务执行。
为了更深入的看清,java线程的本质。
我这里在定义一个任务,挂到线程上去。
package com.css.java.learning.action;
public class Task2 implements Runnable {
protected int countDown = 10;
public String mhtao(){
return "答:可以吃3天!";
}
@Override
public void run() {
while(countDown-->0){
System.err.println(mhtao());
Thread.yield();
}
}
}
线程调用:
package com.css.java.learning.action;
public class Thread1 {
public static void main(String[] args) {
Thread t = new Thread(new Task1(5));
t.start();
Thread t2 = new Thread(new Task2());
t2.start();
System.err.println("线程任务已被java调用!");
}
}
随机性
运行结果一:
运行结果二:
好了,运行结果都在这了。笔者就不多说了。
四、java多线程管家:
这里,笔者科普一下Executor线程池框架!
我们通过上述方法,创建的线程。虽然称之为线程,但他是没人管的野线程。
调用new Thread()创建的线程缺乏管理,而且可以无限制创建,之间相互竞争,会导致过多占用系统资源导致系统瘫痪。 不利于扩展,比如如定时执行、定期执行、线程中断。
我们,得找东西管管它啊。Executor线程管家来喽。
重用存在的线程,减少对象创建、消亡的开销,性能佳
可有效控制最大并发线程数,提高系统资源的使用率,同时避免过多资源竞争,避免堵塞
提供定时执行、定期执行、单线程、并发数控制等功能。
其内部使用了线程池机制,它在java.util.cocurrent 包下,通过该框架来控制线程的启动、执行和关闭,可以简化并发编程的操作。因此,在Java 5之后,通过Executor来启动线程比使用Thread的start方法更好,除了更易管理,效率更好(用线程池实现,节约开销)外,还有关键的一点:有助于避免this逃逸问题——如果我们在构造器中启动一个线程,因为另一个任务可能会在构造器结束之前开始执行,此时可能会访问到初始化了一半的对象用Executor在构造器中。
Executor框架包括:线程池,Executor,Executors,ExecutorService,CompletionService,Future,Callable等。
我们将在下一篇文章,讲述java多线程管家:Executor!
以上是关于浅析java多线程的主要内容,如果未能解决你的问题,请参考以下文章
Java 线程池 ThreadPoolExecutor 八种拒绝策略浅析