多线程的概念:略

多线程的目的:提高效率

主线程:

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类)的更多相关文章

  1. Java学习笔记31(IO:Properties类)

    Properties类,表示一个持久的j集,可以存在流中,或者从流中加载 是Hashtable的子类 map集合的方法都能用 用途之一:在开发项目中,我们最后交给客户的是一个编译过的class文件,客 ...

  2. java学习笔记6--类的继承、Object类

    接着前面的学习: java学习笔记5--类的方法 java学习笔记4--类与对象的基本概念(2) java学习笔记3--类与对象的基本概念(1) java学习笔记2--数据类型.数组 java学习笔记 ...

  3. [core java学习笔记][第四章对象与类]

    4.3 用户自定义类 4.3.1 类数组的声明 需要两次new Employee[]=staff=new Employedd[3]; staff[0]=new Employedd(参数列表); sta ...

  4. java学习笔记(3)——对象与类(日期)

    变量.类型.赋值.运算符等等: https://blog.csdn.net/common77zwq/article/details/81988676 1.概念: 面向对象程序设计OOP.类class. ...

  5. 【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 ...

  6. Java学习笔记(2)--- 对象和类入门,java包,this 和 super区别

    1.对象和类(Object and class): 一个 Java 程序可以认为是一系列对象的集合,而这些对象通过调用彼此的方法来协同工作. 面对对象编程是java非常重要的一部分,作者本身之前学过c ...

  7. java学习笔记15--多线程编程基础2

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...

  8. java学习笔记14--多线程编程基础1

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note14.html,转载请注明源地址. 多线程编程基础 多进程 一个独立程序的每一次运行称为 ...

  9. java学习笔记12--异常处理

    java学习笔记系列: java学习笔记11--集合总结 java学习笔记10--泛型总结 java学习笔记9--内部类总结 java学习笔记8--接口总结 java学习笔记7--抽象类与抽象方法 j ...

随机推荐

  1. java学习--构造方法

    构造方法的作用:创建对象并初始化对象 定义规则:构造方法名与类名相同且没有返回值.(构造方法不需要设置返回值类型,包括void) 在没有定义构造方法是,编译器会自动为类添加形如  类名 () {}  ...

  2. Sql Server数据库之约束

    一.约束的分类 实体约束:关于行的约束,比如某一行出现的值就不允许别的行出现,如主键 域约束:关于列的约束,对表中所有行的某些列进行约束,如check约束 参照完整性约束:如果某列的值必须与其他列的值 ...

  3. Codeforces Round #438 A. Bark to Unlock

    题意:给你一个原串和n个子串,问你这n个子串任意组合起来能不能使原串出现,串的长度为2. Examples Input ya4ahoytoha Output YES Input hp2http Out ...

  4. OpenStack 安装:nova服务

    上一篇介绍了glance,并且成功创建了一个镜像,这一篇介绍Nova. 首先创建Nova用户,需要记得先source环境变量,然后创建Nova用户,并设置密码为nova [root@linux-nod ...

  5. 在网站中使用UEditor富文本编辑器

    UEditor是由百度WEB前端研发部开发的所见即所得的开源富文本编辑器,具有轻量.可定制.用户体验优秀等特点. 官网链接 进入到下载页面,选择相应的版本下载 这里我们使用ASP.NET开发,所以选择 ...

  6. Python+Selenium学习--异常截图

    前言 Webdriver 提供错误截图函数get_screenshot_as_file(),可以帮助我们跟踪bug,在脚本无法继续执行时候, get_screenshot_as_file()函数将截取 ...

  7. HDU 5734 Acperience(数学推导)

    Problem Description Deep neural networks (DNN) have shown significant improvements in several applic ...

  8. 将Promise融会贯通之路

    前端初学者经常会问,我如何在ajax1结束之后才启动ajax2呢?我怎么做才能在所有的ajax结束之后触发某程序呢?亦或是哎真是烦,5个ajax套在一起,原来的逻辑是什么呀! 一个稍微有点经验的前端程 ...

  9. laravel简书(1)

    Laravel的社区生态 中文社区(http://laravel-china.org) 5.4中文文档(http://d.laravel-china.org/docs/5.4) Laravel源码地址 ...

  10. 在桌面创建robotframework Ride的快捷方式启动RIDE

    安装后robotframework-ride 后,每次启动时都要在Dos命令下启动 ,下面是创建快捷方式启动操作如下: 1.进入到python的安装目录的/Scripts目录下,找到ride.py文件 ...