多线程的概念:略

多线程的目的:提高效率

主线程:

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 POI操作Excel注意点

    excel的行索引和列索引都是从0开始,而行号和列号都是从1开始 POI·操作excel基本上都是使用索引 XSSFRow对象的 row.getLastCellNum() 方法返回的是当前行最后有效列 ...

  2. 记号一下selenium+Firefox自动下载的参数

    参考: https://blog.csdn.net/wxstar8/article/details/80782556 https://blog.csdn.net/xiaoguanyusb/articl ...

  3. DB2 公共表表达式(WITH语句的使用)

    ----start 说起WITH 语句,除了那些第一次听说WITH语句的人,大部分人都觉得它是用来做递归查询的.其实那只是它的一个用途而已,它的本名正如我们标题写的那样,叫做:公共表表达式(Commo ...

  4. [leetcode]67. Add Binary 二进制加法

    Given two binary strings, return their sum (also a binary string). The input strings are both non-em ...

  5. Sublime Text3快捷键大全

    选择类 Ctrl+D 选中光标所占的文本,继续操作则会选中下一个相同的文本. Alt+F3 选中文本按下快捷键,即可一次性选择全部的相同文本进行同时编辑.举个栗子:快速选中并更改所有相同的变量名.函数 ...

  6. IntelliJ IDEA常用快捷键(Mac)

    Mac 键盘符号和修饰键说明 ⌘ ——> Command ⇧ ——> Shift ⌥ ——> Option ⌃ ——> Control ↩︎ ——> Return/Ent ...

  7. Python开发——数据类型【列表】

    列表的定义 中括号[]内以逗号分隔开,按照索引,存放各种数据类型,每个位置代表一个元素 list_t = ['张三','Lucy',123] print(list_t) # ['张三', 'Lucy' ...

  8. 在URL地址中传值

    URL: re_path('edit_teacher-(\d+).html', views.handle_edit_teacher), HTML: <a href='/edit_teacher- ...

  9. zeromq学习记录(一)最初的简单示例使用ZMQ_REQ ZMQ_REP

    阅读zeromq guide的一些学习记录 zeromq官方例子 在VC下运行会有些跨平台的错误 我这里有做修改 稍后会发布出来 相关的代码与库  http://download.zeromq.org ...

  10. MybatisMapper 映射框架(增删改查 原始模式)

    //增删改查 package TestDemo; import java.io.IOException; import java.io.InputStream; import java.util.Da ...