一、线程(Thread)

1.线程

线程:是指程序中的顺序流

多线程:一个程序中的多个顺序流同时执行

(1)线程的状态:

新生

就绪

运行

阻塞

终止

(2)学习多线程:

1)线程的创建

2)线程的状态

3)线程的安全

4)线程的通信

2.线程的创建

1)继承Thread,重写run()方法

(1)在run()方法中定义线程体

(2)开启:使用start()方法开启线程

//继承Tread

public class Thread01 extends Thread{

//重写run()方法

//多线程的线程体

@Override

public void run() {

for(int i=1;i<=20;i++){

System.out.println("一边敲代码...");

}

}

public static void main(String[] args) {

//开启多线程 创建线程

Thread01 th=new Thread01();

//开启线程

th.start();

//th.run();   注意:这是方法的调用,不是多线程的开启

for(int i=1;i<=20;i++){

System.out.println("一边聊天...");

}

}

}

2)实现Runnable接口,重写run()方法(推荐使用,线程安全)

开启:通过Tread类中的start()方法开启线程

优点: (1)避免了单继承的局限性

(2)实现资源的共享

public class Thread02 implements Runnable{

//定义线程体的方法,当被调用的时候,会逐行执行里面的代码

@Override

public void run() {

for(int i=1;i<=100;i++){

System.out.println("一边敲代码...");

}

}

public static void main(String[] args) {

Thread02 th=new Thread02();

//开启线程//创建线程

Thread t=new Thread(th);  //因为开启线程的方法在Thread类中,Thread做为代理类出现

t.start();

for(int i=1;i<=100;i++){

System.out.println("一边聊天...");

}

}

}

实现资源共享:

/*

* 模拟铁路12306

* 需求: 100张票,3个人买完

* 资源共享: 100张票

*/

public class Thread03 implements Runnable{

//成员 资源

int tikets=100;

@Override

public synchronized void run() {

//循环买票

while(true){

if(tikets<=0){

break;

}

//捕捉异常

//static void   sleep(long millis) 在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度程序精度和准确性的影响

try {

Thread.sleep(100);  //线程睡眠100ms

} catch (InterruptedException e) {

e.printStackTrace();

}

//static Thread    currentThread() 返回对当前正在执行的线程对象的引用

//String     getName() 返回该线程的名称

System.out.println(Thread.currentThread().getName()+"正在购买第"+tikets--);

}

}

public static void main(String[] args) {

Thread03 th=new Thread03 ();

//开启三个线程

Thread th1=new Thread(th,"张三");

Thread th2=new Thread(th,"李四");

Thread th3=new Thread(th,"王五");

th1.start();

th2.start();

th3.start();

}

}

3)实现Callable接口,重写call()方法,方法中定义线程体(了解)

优点:可以抛出异常,可以有返回值

//导包

import java.util.concurrent.Callable;

import java.util.concurrent.ExecutionException;

import java.util.concurrent.ExecutorService;

import java.util.concurrent.Executors;

import java.util.concurrent.Future;

//实现Callable接口  <>可以添加泛型,引用类型的数据

public class Race05 implements Callable<Integer>{

//存储赢的人的名字

String winner=null;

//重写call()方法,方法中定义线程体

@Override

public Integer call() throws Exception {

//开始游戏,循环停止游戏结束

for(int i=1;i<=100;i++){

if("兔子".equals(Thread.currentThread().getName()) && i%10==0){

try {

Thread.sleep(2);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(Thread.currentThread().getName()+"正在跑第"+i+"步");

//调用有Boolean类型返回值的结束方法

boolean flag=over(i);

//判断返回值是true,或为false

if(flag){

return i;

}

}

return -1;

}

/**

* @param steps  当前线程的步数

* 返回值: 如果有人赢了返回true,否则返回false

*/

public boolean over(int steps){

if(winner!=null){

return true;

}else{

if(steps==100){

winner=Thread.currentThread().getName();

return true;

}

return false;

}

}

public static void main(String[] args) throws InterruptedException, ExecutionException {

Race05 race=new Race05();

//1.创建执行服务

ExecutorService server=Executors.newFixedThreadPool(2);

//2.提交执行

Future result1=server.submit(race);

Future result2=server.submit(race);

//3.获取结果

Integer i1=(Integer) result1.get();

Integer i2=(Integer) result2.get();

System.out.println(i1+"---->"+i2);

//4.关闭服务

server.shutdown();

}

}

2.线程状态问题

1)状态:

新生状态: new

就绪状态: start() 线程就会进入到就绪状态,线程会进入到就绪队列,等待CPU的调度

运行状态:

阻塞状态:非常执行完毕,通过程序进行控制

终止状态:

注意:一个线程一旦进入到终止状态,没有办法恢复了,就算是重写new一个线程,也不刚那个线程了,一个线程一旦进入到阻塞状态,无法直接恢复到运行,等待阻塞接触之后恢复到就绪状态

2)如何进入到就绪状态

1)start()

2)阻塞解除

3)线程切换,被切换的线程进入到就绪状态

4)yield() 礼让线程

3)如何进入到阻塞状态

1)sleep() 方法

2)join()

3)wait()

4)如何让一个线程进入到终止状态

1)正常执行完毕

2)destroy() |stop() 已过时

3)通过标识手动判断

3.Thread类的方法学习

1)sleep() 线程休眠

1.模拟网络延迟

2.放大问题的可能性

注意:sleep() 线程的休眠是抱着资源不放进行休眠,同步的是对象资源,让出的是CPU的资源

//实现Runnable接口

public class State01 implements Runnable{

public static void main(String[] args) {

new Thread(new State01()).start();

}

/*

* 倒计时  10 9 8 7 6 5 4 3 2 1

* 重写run()方法

*/

@Override

public void run() {

for(int i=10;i>=0;i--){

//模拟网络延迟

try {

Thread.sleep(1000);   //sleep() 线程的休眠1000ms=1s

} catch (InterruptedException e) {

e.printStackTrace();

}

if(i==0){

System.out.println("过年好...");

break;

}

System.out.println(i);

}

}

}

2)yield() 礼让线程

static Thread   currentThread()

返回对当前正在执行的线程对象的引用

String   getName()

返回该线程的名称

//static void     yield() 暂停当前正在执行的线程对象,并执行其他线程

public class Yield03 implements Runnable{

public static void main(String[] args) {

new Thread(new Yield03(),"A").start();

new Thread(new Yield03(),"B").start();

}

@Override

public void run() {

System.out.println(Thread.currentThread().getName()+"start...");

//yield() 礼让线程,等待CPU的再度调用,但是是随机分配

Thread.yield();  //静态方法

System.out.println(Thread.currentThread().getName()+"end...");

}

}

3)getState() 方法

Thread.State  getState()

返回该线程的状态

void  setPriority(int newPriority)

更改线程的优先级

/*

* getState() 方法

* 线程的优先级: 提高优先执行的可能性,但是不一定就会先执行

* void setPriority(int newPriority) 更改线程的优先级。

* 优先级分为1~10 1最小  10最大

* Thread.NORM_PRIORITY 5 (默认为5)

* Thread.MAX_PRIORITY  10

* Thread.MIN_PRIORITY  1

*/

public class GetState04 {

public static void main(String[] args) {

Thread th=new Thread(()->{

for(int i=1;i<=10;i++){

try {

Thread.sleep(100);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println("一边学习...");

}

});

th.setPriority(Thread.NORM_PRIORITY);

System.out.println(th.getPriority());

System.out.println(th.getState());//NEW

th.start();

System.out.println(th.getState());//RUNNABLE

for(int i=1;i<=10;i++){

if(i==5){

try {

Thread.sleep(500);

} catch (InterruptedException e) {

e.printStackTrace();

}

}

System.out.println(th.getState());

}

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(th.getState());

if(th.getState()== Thread.State.TERMINATED){

System.out.println("终止");

}

}

}

4)join() 合并线程,插队线程

void join()

等待该线程终止。

void join(long millis)

等待该线程终止的时间最长为 millis 毫秒。

void join(long millis, int nanos)

等待该线程终止的时间最长为 millis 毫秒 + nanos 纳秒

/*

* join() 合并线程,插队线程

模拟:父亲让儿子去买烟的过程

*/

public class JoinDemo05 {

public static void main(String[] args) {

new Thread(new Father()).start();

}

}

class Father implements Runnable{

@Override

public void run() {

System.out.println("想抽烟...");

System.out.println("给儿子钱,让儿子去买烟..");

Thread th=new Thread(new Son());

th.start();

try {

th.join();//合并线程

} catch (InterruptedException e) {

e.printStackTrace();

System.out.println("儿子丢了,赶紧去找儿子..");

}

System.out.println("接过烟,吸一口,啊~");

}

}

class Son  implements Runnable{

@Override

public void run() {

System.out.println("接过前,给老爸去买烟...");

System.out.println("路边有个电玩城,进去玩10s...");

for(int i=1;i<=10;i++){

try {

Thread.sleep(1000);

} catch (InterruptedException e) {

e.printStackTrace();

}

System.out.println(i+"s...");

}

System.out.println("赶紧去买烟...");

System.out.println("把烟给老爸,前揣兜里...");

}

}

4.线程安全

多个线程同时操作同一个外汇MT4教程资源的时候,才可能会出现线程安全问题

1)synchronized关键字

通过同步synchronized关键字控制线程安全:

同步方法 :

静态方法

成员方法

同步块 synchronized (类|this|资源){代码}

类: 类名.class 一个类的Class对象 一个类只有一个Class对象

//通过同步synchronized关键字控制线程安全

public class Single01 {

public void main(String[] args) {

new Thread(()->{System.out.println(Single.newInstance());}).start();;

new Thread(()->{System.out.println(Single.newInstance());}).start();;

}

}

class Single{

//2.私有的静态的该类的引用

private static Single single=null;

//1.构造器私有话

private Single(){}

//3.公共的静态的方法

//在方法上添加锁,锁方法

/*public static synchronized Single newInstance(){

if(single==null){

single=new Single();

}

return single;

}*/

//同步块

/*public static Single newInstance(){

synchronized (Single.class) {  //控制多线程排队执行

if(single==null){

single=new Single();

}

}  //{}中的代码就是排队执行的代码

return single;

}*/

public static Single newInstance(){

if(single==null){

//A B C

synchronized (Single.class) {  //控制多线程排队执行

//双重检查 double check

if(single==null){

single=new Single();

}

}  //{}中的代码就是排队执行的代码

}

return single;

}

}

————————————————

原文链接:https://blog.csdn.net/zhiruochujian1/article/details/102881453

浅谈JAVA线程的更多相关文章

  1. 浅谈Java线程安全

    浅谈Java线程安全 - - 2019-04-25    17:37:28 线程安全 Java中的线程安全 按照线程安全的安全程序由强至弱来排序,我们可以将Java语言中各种操作共享的数据分为以下五类 ...

  2. 浅谈 Java线程状态转换及控制

    线程的状态(系统层面) 一个线程被创建后就进入了线程的生命周期.在线程的生命周期中,共包括新建(New).就绪(Runnable).运行(Running).阻塞(Blocked)和死亡(Dead)这五 ...

  3. 浅谈Java 线程池原理及使用方式

    一.简介 什么是线程池? 池的概念大家也许都有所听闻,池就是相当于一个容器,里面有许许多多的东西你可以即拿即用.java中有线程池.连接池等等.线程池就是在系统启动或者实例化池时创建一些空闲的线程,等 ...

  4. 浅谈java线程池实现

    再进入主题之前,我们先了解几个概念,对读源码有所帮助,对于线程池的运行状态,有4个级别,分别是RUNNING,SHUTING,STOP,TIDING,TERMINATED 解释如下: The runS ...

  5. 浅谈JAVA集合框架

    浅谈JAVA集合框架 Java提供了数种持有对象的方式,包括语言内置的Array,还有就是utilities中提供的容器类(container classes),又称群集类(collection cl ...

  6. 浅谈java性能分析

    浅谈java性能分析,效能分析 在老师强烈的要求下做了效能分析,对上次写过的词频统计的程序进行分析以及改进. 对于效能分析:我个人很浅显的认为就是程序的运行效率,代码的执行效率等等. java做性能测 ...

  7. !! 浅谈Java学习方法和后期面试技巧

    浅谈Java学习方法和后期面试技巧 昨天查看3303回复33 部落用户大酋长 下面简单列举一下大家学习java的一个系统知识点的一些介绍 一.java基础部分:java基础的时候,有些知识点是非常重要 ...

  8. 浅谈Java的集合框架

    浅谈Java的集合框架 一.    初识集合 重所周知,Java有四大集合框架群,Set.List.Queue和Map.四种集合的关注点不同,Set 关注事物的唯一性,List 关注事物的索引列表,Q ...

  9. 浅谈java类集框架和数据结构(2)

    继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...

随机推荐

  1. java面试题最容易犯错

    1. static 和 final 的用法 static 的作用从三个方面来谈,分别是静态变量.静态方法.静态类. 静态变量:声明为 static 的静态变量实质上就是全局变量,当声明一个对象时,并不 ...

  2. SQL中LEFT JOIN ON AND 与 LEFT JOIN ON WHERE的区别

    数据库在通过连接两张或多张表来返回记录时,都会生成一张中间的临时表,然后再将这张临时表返回给用户. ON...WHERE ' order by ts.id SQL执行过程: 生成临时表: ON条件:  ...

  3. 「NOI2017」整数 解题报告

    「NOI2017」整数 有一些比较简单的\(\log^2n\)做法 比如暴力在动态开点线段树上维护每个位置为\(0\)还是\(1\),我们发现涉及到某一位加上\(1\)或者减去\(1\)实际上对其他位 ...

  4. 【dart学习】之字典(Map)的相关方法总结

    一,概述 通常来讲,Map是一个键值对相关的对象,键和值可以是任何类型的对象.每个键只出现一次,而一个值则可以出现多次.映射是动态集合. 换句话说,Maps可以在运行时增长和缩小. dart:core ...

  5. SCP-bzoj-1079

    项目编号:bzoj-1079 项目等级:Safe 项目描述: 戳这里 特殊收容措施: DP.普通的状压状态数515,显然TLE+MLE,我们考虑把底数和幂换一换,压成155的状态数. 故状态设计为:f ...

  6. Python基础教程(012)--排查手误错误

    前言 排查由于手误书写错误的方法 内容 手动输入错误的时候,颜色是红色 函数名称写错 1,颜色不一样 2,nameError错误 掌握知识点 学会在写代码的时候排查错误

  7. c#如何写服务,打包和卸载服务

    Service.cs  每隔一分钟进行一次数据操作 public Service1()        {            InitializeComponent();            Sy ...

  8. 75 OpenCV编译、图像处理等

    0 引言 记录图像处理的一些经验和使用OpenCV 等库的注意事项. 1 opencv中的坐标系 一图以蔽之~ 2 opencv 3.4.0 + opencv_contrib + qt编译 主要参考了 ...

  9. JavaScript--字符串与JSON对象相互转换

    JSON.parse() 兼容性:Chrome,Firefox (Gecko) 3.5 (1.9.1),IE 8.0,Safari 4.0 JSON.parse('[1, 5, "false ...

  10. 三种做法:BZOJ 2780: [Spoj]8093 Sevenk Love Oimaster

    目录 题意 思路 AC_Code1 AC_Code2 AC_Code3 参考 @(bzoj 2780: [Spoj]8093 Sevenk Love Oimaster) 题意 链接:here 有\(n ...