Java学习笔记44(多线程一:Thread类)
多线程的概念:略
多线程的目的:提高效率
主线程:
package demo;
//主线程
public class Demo {
public static void main(String[] args) {
function();
System.out.println(1);
} public static void function(){
for (int i = 0; i < 10000; i++) {
System.out.println(i);
}
}
}
这段简单的代码,我们发现:
必须要先执行方法输出完10000次的数字后才可以打印第二行的数字1
那么有没有方法,可以做到在执行方法的同时执行第二行的输出?
Thread类
创建新线程的两种方法:
第一种:
package demo; public class SubThread extends Thread {
//重写run方法
public void run(){
for(int i = 0 ; i< 50 ; i++){
System.out.println(i+"run");
}
}
}
package demo; public class ThreadDemo {
public static void main(String[] args) {
SubThread st1 = new SubThread();
st1.start();
for (int i = 0; i < 50; i++) {
System.out.println(i+"main");
}
}
}
这里输出时候,发现打印的run和main随机出现,交错出现,而不像以前那样按顺序打印
原因:创建了新的线程,两条线程由cpu选择执行,我们无法控制
start方法开启新的线程,继承了Thread类因为只有继承了它才可以操作线程
重写run方法因为,Thread类本身没有写入有意义的run方法,相当于一个模板,供开发者使用
线程名:
每个线程都有自己的名字,主线程名:main,其他新建线程默认名:Thread-n
获取、修改线程名:
package demo1; public class NameThread extends Thread {
public void run(){
System.out.println(super.getName());
//输出:默认是Thread-0,如果修改了,就是hello
}
}
package demo1; public class ThreadDemo {
public static void main(String[] args) {
NameThread nt1 = new NameThread();
nt1.setName("hello");
//修改线程名为hello,主线程不能改名
nt1.start(); Thread t = Thread.currentThread();
System.out.println(t.getName());
//输出:main
}
}
Thread类的一个实用方法:
package demo1; public class ThreadDemo {
public static void main(String[] args) throws InterruptedException {
for (int i = 0; i < 10; i++) {
Thread.sleep(1000);
System.out.println(i);
}
//每次打印都会等待一秒,参数是毫秒值
}
}
第二种创建线程方法:
package demo1; public class SubRunnable implements Runnable {
public void run() {
for (int i = 0; i < 50; i++) {
System.out.println(i + "run");
}
}
}
package demo1; public class ThreadDemo {
public static void main(String[] args) {
SubRunnable sr1 = new SubRunnable();
Thread t1 = new Thread(sr1);
t1.start();
for (int i = 0; i < 50; i++) {
System.out.println(i + "main");
}
}
}
这种方式好处:
1.接口可以多实现,避免了单继承的局限性
2.线程和方法分离,更符合面向对象的特点
3.资源实现共享
这两种方式可以实用匿名内部类实现:
package demo1; public class ThreadDemo {
public static void main(String[] args) {
// 继承方式
new Thread() {
public void run() {
System.out.println("1");
}
}.start(); // 实现接口方式
new Thread(new Runnable() {
public void run() {
System.out.println(2);
}
}).start(); }
}
线程的状态:
1.新建状态:new Thread()创建线程对象
2.运行状态:使用了start()方法进入运行状态
3.退出状态:run方法结束,或者调用了stop方法(已过时,不建议实用)
4.阻塞状态:有时候使用了start方法,但不一定立即运行,或者运行之后CPU由于一些原因不再分配,由运行状态转到阻塞状态
5.休眠状态:前边提到的sleep方法就是这种状态,也有可能转到阻塞状态或者运行状态
6.等待状态:wait方法,无限等待,notify方法可以唤醒线程,可能转到运行或阻塞状态
注意:受阻塞是等待CPU的资源,休眠等待是放弃CPU的执行
线程池的概念:
一个容器,存入多个线程,需要时候,拿出执行,
运行结束后线程再回到容器中,这种方式可以提高效率
实现线程池:
package demo1; public class ThreadPoolRunnable implements Runnable {
public void run(){
System.out.println(Thread.currentThread().getName()+"线程提交任务");
//输出: pool-1-thread-1线程提交任务
// pool-1-thread-2线程提交任务
}
package demo1; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class ThreadPoolDemo {
public static void main(String[] args) {
//调用工厂类的方法创建线程池
ExecutorService es1 = Executors.newFixedThreadPool(2);
es1.submit(new ThreadPoolRunnable());
es1.submit(new ThreadPoolRunnable());
//运行后不会停 es1.shutdown();//销毁线程池,不常用
}
}
实现线程的Callable接口方式:
它弥补了Runnable方式的缺陷:无法抛出异常,并且有返回值
使用方法和Runnable方式基本一致:
示例:
package demo1; import java.util.concurrent.Callable; public class ThreadPoolCallable implements Callable<String>{
public String call(){
return "a";
}
}
package demo1; import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; public class ThreadPoolDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
ExecutorService es1 = Executors.newFixedThreadPool(2);
Future<String>f1 = es1.submit(new ThreadPoolCallable());
String s1 = f1.get();
System.out.println(s1);
//得到返回值,输出a
}
}
简单应用:多线程异步计算
使用两个线程计算求和:
package demo1; import java.util.concurrent.Callable; public class GetSumCallable implements Callable<Integer> {
private int a; public GetSumCallable(int a) {
this.a = a;
} public Integer call() {
int sum = 0;
for (int i = 0; i <= a; i++) {
sum += i;
}
return sum;
}
}
package demo1; import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future; public class ThreadPoolDemo {
public static void main(String[] args) throws Exception {
ExecutorService es1 = Executors.newFixedThreadPool(2);
Future<Integer> f1 = es1.submit(new GetSumCallable(100));
Future<Integer> f2 = es1.submit(new GetSumCallable(300));
System.out.println(f1.get());
System.out.println(f2.get());
es1.shutdown();
}
}
Java学习笔记44(多线程一:Thread类)的更多相关文章
- Java学习笔记31(IO:Properties类)
Properties类,表示一个持久的j集,可以存在流中,或者从流中加载 是Hashtable的子类 map集合的方法都能用 用途之一:在开发项目中,我们最后交给客户的是一个编译过的class文件,客 ...
- java学习笔记6--类的继承、Object类
接着前面的学习: java学习笔记5--类的方法 java学习笔记4--类与对象的基本概念(2) java学习笔记3--类与对象的基本概念(1) java学习笔记2--数据类型.数组 java学习笔记 ...
- [core java学习笔记][第四章对象与类]
4.3 用户自定义类 4.3.1 类数组的声明 需要两次new Employee[]=staff=new Employedd[3]; staff[0]=new Employedd(参数列表); sta ...
- java学习笔记(3)——对象与类(日期)
变量.类型.赋值.运算符等等: https://blog.csdn.net/common77zwq/article/details/81988676 1.概念: 面向对象程序设计OOP.类class. ...
- 【Todo】Java学习笔记 100==100 & Reflection API & Optional类详解 & DIP、IoC、DI & token/cookie/session管理会话方式
为什么1000 == 1000返回为False,而100 == 100会返回为True? Link Java Reflection API:Link Java8 Optional 类深度解析: L ...
- Java学习笔记(2)--- 对象和类入门,java包,this 和 super区别
1.对象和类(Object and class): 一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作. 面对对象编程是java非常重要的一部分,作者本身之前学过c ...
- java学习笔记15--多线程编程基础2
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...
- java学习笔记14--多线程编程基础1
本文地址:http://www.cnblogs.com/archimedes/p/java-study-note14.html,转载请注明源地址. 多线程编程基础 多进程 一个独立程序的每一次运行称为 ...
- java学习笔记12--异常处理
java学习笔记系列: java学习笔记11--集合总结 java学习笔记10--泛型总结 java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 j ...
随机推荐
- mac下安装cnpm淘宝镜像
cnpm:官网 (事先已经安装了node,有npm)查看官网,提示安装需运行命令:npm install -g cnpm --registry=https://registry.npm.taobao. ...
- springmvc controller方法返回值
- java学习笔记(五):公共类
什么是公共类,公共类就是和源文件名同名的类,举例来说:类的名称是 public class aaa{},那么源文件就应该是 aaa.java. 每个源文件中只能有一个公共类. 每个源文件可以有很多非公 ...
- poj 1639 最小k度限制生成树
题目链接:https://vjudge.net/problem 题意: 给各位看一下题意,算法详解看下面大佬博客吧,写的很好. 参考博客:最小k度限制生成树 - chty - 博客园 https:/ ...
- react官方脚手架搭建项目
1.全局安装 npm install -g create-react-app 2. app后面还要给项目文件命名 create-react-app //是全局命令来创建react项目 3.然后按照提示 ...
- time模块的使用
https://www.cnblogs.com/jimmy-share/p/10605575.html import time 一.方法汇总: time.sleep():定时函数 time.time( ...
- java_22 Map接口
1Map Collection是孤立存在的,向集合中存储元素是一个一个放进去的 Map中的集合存储是成对的,可以通过键找到值.即将键映射到值的对象.一个映射不能包含重复的键:每个键最多只能映射到一个值 ...
- 真·浅谈treap树
treap树是一种平衡树,它有平衡树的性质,满足堆的性质,是二叉搜索树,但是我们需要维护他 为什么满足堆的性质?因为每个节点还有一个随机权值,按照随机权值维持这个堆(树),可以用O(logn)的复杂度 ...
- python 安装第三方包时 read timed out
记录下安装python第三方包超时报错,解决方法:(以安装numpy为例) pip install numpy 报错:raise ReadTimeoutError(self._pool, None, ...
- VBA找相似体积的单元格值
在VBA中做了一个比较体积,如果体积相似就显示隔壁单元格的内容 Function VC(a, b As Range) 'VolumeCompare体积比较 Dim arry() As Variant ...