Java并发之基本的线程机制
来源:互联网 发布:ubuntu samba 权限 编辑:程序博客网 时间:2024/05/22 14:38
并发
先说说Java代码的执行机制:java代码–》编译后成为java字节码–》字节码被类加载器加载到JVM–》JVM执行字节码–》最终转换成汇编指令在CPU执行
关于并发:
使用并发需要解决的问题有多个,实现并发的方式也有多种。
1. 基本的线程机制
1.1 实现线程的基本方法:
1.1.1 实现Runnable接口来定义任务
通过实现Runnable接口并编写run()方法来是实现一个线程类。
public class MyThread implements Runnable{ public void run(){ }}//使用:MyThread myThread = new MyThread();myThread.run();//开始执行线程
1.1.2 通过Thread类
将一个实现了Runnable接口的类作为参数传递给Thread构造器来实现线程:
Thread thread = new Thread(new MyThread());thread.start();//开始执行线程,start()方法会自动调用run()方法。其实start()会很快的返回,因为这个start()方法是有由main这线程执行的
1.2 关键方法解析
1.2.1 Thread.yield()方法:
这是一个静态方法,对该方法的调用表示对线程调度器的一种建议,声明:我已经执行完声明周期中最重要的部分了,此时可以把CPU切换给别的线程使用了。(简单点理解可以是降低当前线程的优先级,主动让出CPU)
1.3 使用Executor执行器(启动线程的优先选择)
Executor是在客户端和执行任务中间提供了一个间接层,帮我们管理线程对象从而简化并发编程。
我们一般使用Executor的子接口ExecutorService,ExecutorService知道如何构建恰当的上下文来执行Runnable对象。下面是一个典型的例子:
public class CachedThreadPool { public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); for(int i = 0; i < 5; i++) exec.execute(new LiftOff()); exec.shutdown(); }}
这是很常见的情况,单个Executor来创建和管理所有的任务。
shutdown()方法的调用可以禁止新的任务呗提交给这个Executor,当前线程(示例中的main线程)将继续运行shutdown()调用之前所提交给Executor的所有任务,知道全部完成之后这个程序将尽快退出。
Executors创建的一些常用的线程池:
1.4 从任务中产生返回值
Runnable是执行工作的独立任务,但是它没有返回值。如果我们希望任务在完成时能够返回一个值,那么可以通过实现Callable接口而不是Runnable接口。Callable是一种具有类型参数的泛型,它的类型是从call()(而不是run()方法)中返回的值的类型。并且使用ExecutorService.submit()方法调用它。下面是一个简单示例:
import java.util.ArrayList;import java.util.concurrent.Callable;import java.util.concurrent.ExecutorService;import java.util.concurrent.Executors;import java.util.concurrent.Future;/** * 从任务中产生返回值;返回值类型为Callable泛型的类型 * @author LL */class TaskWithResult implements Callable<String> { private int id; public TaskWithResult(int id){ this.id = id; } //任务 public String call() throws Exception { return "result of TaskWithResult " + id; }}/** * function: 从任务中产生返回值.并打印 * @author LL */public class CallableDemo { public static void main(String[] args) { ExecutorService exec = Executors.newCachedThreadPool(); //Future 表示异步计算的结果。它提供了检查计算是否完成的方法,以等待计算的完成,并获取计算的结果。计算完成后只能使用 get 方法来获取结. //这个list用来保存每个任务的返回结果 ArrayList< Future<String> > results = new ArrayList<Future<String>>(); for (int i=0; i<10; i++){ //submit()提交一个返回值的任务用于执行,返回一个表示任务的未决结果的 Future。 //把返回的结果添加到List Future<String> fs = exec.submit(new TaskWithResult(i)); results.add(fs); } for (Future<String> fs : results) { try { System.out.println(fs.get()); } catch (Exception e) { e.printStackTrace(); } finally{ exec.shutdown();//启动一次顺序关闭,执行以前提交的任务,但不接受新任务。 } } }}
submit()方法会产生Future对象,它用Callable返回结果的特定类型进行了参数化。我们可以通过isDone()方法查看Future是否已经完成。当任务完成时我们可以通过调用get()方法来获取该结果。不过不用isDone()方法检查,get()方法将会阻塞知道获取到结果。
1.5 休眠
影响任务行为的一种简单方法是调用sleep()方法,这将使任务中止执行给定的时间。现在一般用TimeUnit这个类显示指定的函数代替原来的函数:当前线程休眠
//Thread.sleep(100);TimeUnit.MILLISECONDS.sleep(100);
1.6 优先级
我们一般在run()方法里面设置线程的优先级,如下所示
public void run(){ Thread.currentThread().setPriority(int) ......}
不同的系统有不同等级的优先级,windows下一般只有7个优先级,而Solaris有2^31 个优先级,所以我们一把只设置三个优先级:Thread类下的静态常量
- static int MAX_PRIORITY 线程可以具有的最高优先级。
- static int MIN_PRIORITY 线程可以具有的最低优先级。
- static int NORM_PRIORITY 分配给线程的默认优先级。
1.7 后台线程
后台线程:指程序运行时在后台提供一种通用服务的线程,并且这种线程并不属于程序中不可或缺的部分。故当程序中所有的非后台线程结束时,程序也就终止了同时会杀死进程中所有的后台线程。
1)设置线程为后台线程的方法:
Thread t = new Thread(new LiftOff());t.setDaemon(true);//设置为后台线程
1.8 加入一个线程
一个线程A可以在另外的一个线程B之上(一般是run()方法里面)调用join方法,其结果是等待一段时间知道后一个线程结束才继续执行。比如:
1. 若在线程t上(t的run()方法中)调用线程s的s.join()方法(s一般作为t的构造器参数传入),则线程t将别挂起,直到线程s结束为止,t才可恢复继续执行。
2. 若在线程t上(t的run()方法中)调用t.join(),则当前线程会被挂起,直到线程t结束。
- Java并发之基本的线程机制
- Java 并发:基本的线程机制
- Java并发(1) 基本的线程机制
- Java并发编程-1 基本线程机制
- 并发(1)基本的线程机制
- Java并发编程实践之线程的基本控制
- Java线程的基本机制
- java并发编程——基本线程机制1
- 初阶并发编辑之——基本的线程机制
- Java编程思想-并发-基本的线程机制/共享受限资源
- java中的并发:线程的基本使用
- java高并发-线程的基本使用
- 并发的基本机制
- java基本线程机制
- 并发机制之线程1
- Java并发学习之四——操作线程的中断机制
- Java并发之线程
- Java并发之线程
- 足以应付一切的水仙花数,字母交叉问题,数组排序去重复,今天get到一点点,首先一道题莫名其妙地改对了然后明白了自己思路是对的但是不会写代码 还是什么用都没有
- jQuery on: losing attached event after rendering partially by AJAX call
- 第27天 批处理、对象的克隆、内存溢出、设计模式、反射
- python 学习笔记-变量作用域
- mysql命令
- Java并发之基本的线程机制
- 关于android内存优化的几点建议
- python学习笔记-1:pycharm安装以及编写显示“Hello python”
- QT tcp粘包问题
- 大学只待成追忆,只是工作已半年,2016再见
- mysql 行级锁的使用以及死锁的预防
- 电感啸叫和LDO啸叫
- Android 实现视屏播放器、边播边缓存功能、外加铲屎(IJKPlayer)
- SSL是如何工作的