文章最前: 我是Octopus,这个名字来源于我的中文名--章鱼;我热爱编程、热爱算法、热爱开源。所有源码在我的个人github ;这博客是记录我学习的点点滴滴,如果您对 Python、Java、AI、算法有兴趣,可以关注我的动态,一起学习,共同进步。
相关文章:
- 多线程的应用与原理分析1
- 多线程的应用与原理分析2(线程的状态)
- 多线程的应用与原理分析3(原子性、可见性、有序性)
- 多线程的应用与原理分析4(synchronized)
- 多线程的应用与原理分析5(ReentrantLock)
- 多线程的应用与原理分析6(ReentrantLock)
- 多线程的应用与原理分析7(Condition)
- 多线程的应用与原理分析8(countdownlatch)
- 多线程的应用与原理分析9(原子操作)
- 多线程的应用与原理分析10(Semaphore)
- 多线程的应用与原理分析11(线程池)
文章目录:
1.多线程最终解决的就是“等待”问题,它的简单使用场景:
1)通过并行计算提高程序执行性能;
2)需要等待网络,1/0响应导致耗费大量的执行时间,可以采用异步线程的方式减少阻塞;
2.tomcat7以前的io模型
多线程的应用场景
1)客户端阻塞:如果客户端只有一个线程,这个线程发起读取文件的操作必须等到IO流返回,线程(客户端)才能做其他的事
2)线程级别阻塞BIO:客户端一个线程情况下,导致整个客户端阻塞;
可以使用多线程,一部分线程在等待IO操作返回其他线程可以继续做其他的事;此时从客户端角度来说,客户端没有闲着。
如何使用多线程?
在java中,有多种方式来实现多线程,继承Thread类,实现Runnable接口,使用ExecutorService,Callable,Future实现带返回值结果的多线程。
1)继承thread创建线程
Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start方法,start是一个native方法,它会启动一个新线程,并执行run方法,这种方式实现多线程很简单,通过自己的类直接extend thread,并覆写run方法,就可以启动新线程并执行自己定义的run方法。
package lock;
/**
* @author zhangyu
* @version V1.0
* @ClassName: MyThread
* @Description: 继承Thread类
* @date 2019/1/19 19:04
**/
public class MyThread extends Thread {
public void run() {
System.out.println("my thread run");
}
public static void main(String[] args) {
MyThread thread1 = new MyThread();
MyThread thread2 = new MyThread();
thread1.start();
thread2.start();
}
}
2)实现Runnable接口创建线程
如果已经继承了一个类,就无法继承Thread了,此时可以实现一个Runnable的接口;
package lock;
/**
* @author zhangyu
* @version V1.0
* @ClassName: MyThread2
* @Description: 实现runnable接口
* @date 2019/1/19 19:07
**/
public class MyThread2 implements Runnable {
@Override
public void run() {
System.out.println("myThread2 run");
}
public static void main(String[] args) {
MyThread2 myThread1 = new MyThread2();
MyThread2 myThread2 = new MyThread2();
Thread t1 = new Thread(myThread1);
Thread t2 = new Thread(myThread2);
t1.start();
t2.start();
}
}
3)实现Callable接口通过FutureTask包装器来创建Thread线程
有时,我们需要让一步执行的线程在执行完成以后,提供一个返回值给到当前的主线程,主线程需要依赖这个值进行后续的逻辑处理,那么这个时候,就需要带返回值的线程。
package lock.callable;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* @author zhangyu
* @version V1.0
* @ClassName: CallableDemo
* @Description: 带返回值的多线程
* @date 2019/1/19 19:10
**/
public class CallableDemo implements Callable<String> {
@Override
public String call() throws Exception {
int a = 1;
int b = 2;
System.out.println(a + b);
return "执行结果:" + (a + b);
}
public static void main(String[] args) throws Exception {
ExecutorService executorService = Executors.newFixedThreadPool(1);
CallableDemo callableDemo = new CallableDemo();
Future<String> future = executorService.submit(callableDemo);
System.out.println(future.get());
executorService.shutdown();
}
}
线程使用的更优雅
合理利用异步操作,大大提升程序的处理性能,zookeeper中就是通过阻塞队列以及多线程的方式,实现对请求的异步化处理,提升性能:
1.Request.java
package lock.demo;
/**
* @author zhangyu
* @version V1.0
* @ClassName: Request
* @Description: 请求的bean
* @date 2019/1/19 19:16
**/
public class Request {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String toString() {
return "request{" + "name=" + name + "\'" + '}';
}
}
2.RequestProcessor.java
package lock.demo;
/**
* @author zhangyu
* @version V1.0
* @ClassName: RequestProcessor
* @Description: 接口
* @date 2019/1/19 19:18
**/
public interface RequestProcessor {
void processRequest(Request request);
}
3.PrintProcessor.java
package lock.demo;
import java.util.concurrent.LinkedBlockingQueue;
/**
* @author zhangyu
* @version V1.0
* @ClassName: PrintProcessor
* @Description: TOTO
* @date 2019/1/19 19:19
**/
public class PrintProcessor extends Thread implements RequestProcessor {
LinkedBlockingQueue<Request> requests = new LinkedBlockingQueue<>();
private final RequestProcessor nextProcessor;
public PrintProcessor(RequestProcessor nextProcessor) {
this.nextProcessor = nextProcessor;
}
public void run() {
while (true) {
try {
Request request = requests.take();
System.out.println("pring data:" + request.getName());
nextProcessor.processRequest(request);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
//进行处理请求
@Override
public void processRequest(Request request) {
requests.add(request);
}
}
4.SaveProcessor.java
package lock.demo;
import java.util.concurrent.LinkedBlockingQueue;
/**
* @author zhangyu
* @version V1.0
* @ClassName: SaveProcessor
* @Description: 保存信息
* @date 2019/1/19 19:24
**/
public class SaveProcessor extends Thread implements RequestProcessor {
LinkedBlockingQueue<Request> requests = new LinkedBlockingQueue<>();
public void run() {
while (true) {
try {
Request request = requests.take();
System.out.println("begin save request info:" + request);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
// 处理请求
@Override
public void processRequest(Request request) {
requests.add(request);
}
}
5.Demo.java
package lock.demo;
/**
* @author zhangyu
* @version V1.0
* @ClassName: Demo
* @Description: 测试
* @date 2019/1/19 19:27
**/
public class Demo {
PrintProcessor printProcessor;
protected Demo() {
SaveProcessor saveProcessor = new SaveProcessor();
saveProcessor.start();
printProcessor = new PrintProcessor(saveProcessor);
printProcessor.start();
}
private void doTest(Request request) {
printProcessor.processRequest(request);
}
public static void main(String[] args) {
Request request = new Request();
request.setName("zhangyu");
new Demo().doTest(request);
}
}