浅谈JAVA线程
一、线程(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线程的更多相关文章
- 浅谈Java线程安全
浅谈Java线程安全 - - 2019-04-25 17:37:28 线程安全 Java中的线程安全 按照线程安全的安全程序由强至弱来排序,我们可以将Java语言中各种操作共享的数据分为以下五类 ...
- 浅谈 Java线程状态转换及控制
线程的状态(系统层面) 一个线程被创建后就进入了线程的生命周期.在线程的生命周期中,共包括新建(New).就绪(Runnable).运行(Running).阻塞(Blocked)和死亡(Dead)这五 ...
- 浅谈Java 线程池原理及使用方式
一.简介 什么是线程池? 池的概念大家也许都有所听闻,池就是相当于一个容器,里面有许许多多的东西你可以即拿即用.java中有线程池.连接池等等.线程池就是在系统启动或者实例化池时创建一些空闲的线程,等 ...
- 浅谈java线程池实现
再进入主题之前,我们先了解几个概念,对读源码有所帮助,对于线程池的运行状态,有4个级别,分别是RUNNING,SHUTING,STOP,TIDING,TERMINATED 解释如下: The runS ...
- 浅谈JAVA集合框架
浅谈JAVA集合框架 Java提供了数种持有对象的方式,包括语言内置的Array,还有就是utilities中提供的容器类(container classes),又称群集类(collection cl ...
- 浅谈java性能分析
浅谈java性能分析,效能分析 在老师强烈的要求下做了效能分析,对上次写过的词频统计的程序进行分析以及改进. 对于效能分析:我个人很浅显的认为就是程序的运行效率,代码的执行效率等等. java做性能测 ...
- !! 浅谈Java学习方法和后期面试技巧
浅谈Java学习方法和后期面试技巧 昨天查看3303回复33 部落用户大酋长 下面简单列举一下大家学习java的一个系统知识点的一些介绍 一.java基础部分:java基础的时候,有些知识点是非常重要 ...
- 浅谈Java的集合框架
浅谈Java的集合框架 一. 初识集合 重所周知,Java有四大集合框架群,Set.List.Queue和Map.四种集合的关注点不同,Set 关注事物的唯一性,List 关注事物的索引列表,Q ...
- 浅谈java类集框架和数据结构(2)
继续上一篇浅谈java类集框架和数据结构(1)的内容 上一篇博文简介了java类集框架几大常见集合框架,这一篇博文主要分析一些接口特性以及性能优化. 一:List接口 List是最常见的数据结构了,主 ...
随机推荐
- mysql查询表的创建时间
mysql查询表的创建时间 查询语句: SELECT table_name,create_time FROM information_schema.TABLES;
- Docker部署Flask应用
创建应用 首先,编写一个简单的Flask应用:docker_test/flask_app.py Docker 安装 请根据自己的操作系统自行安装. Docker简介 Docker 镜像 Docker镜 ...
- 【和孩子一起学编程】 python笔记--第三天
第十章 游戏时间:Skier 首先安装pygame,直接在cmd命令控制框里键入pip install pygame就可以了 代码: import pygame, sys, random skier_ ...
- hdu 4705 Y (树形dp)
Description Input 4 1 2 1 3 1 4 题目的意思是给你一棵树,让你找到所有不在一条路径上的三个点的情况个数.乍一看正向处理比较麻烦,我们从反方向考虑,如果是取在一条路径上的3 ...
- Android中可以做的两件坏事---破解锁屏密码和获取Wifi密码
之前的文章一直在介绍OC,最近也是在找急忙慌的学习IOS,所以Android方面的知识分享就有点中断了,但是我现在还是要靠Android吃饭,所以不能Android的工作不能停呀,今天咋们来看一下我在 ...
- tidb集群
tidb ansible部署 https://zhuanlan.zhihu.com/p/27308307?refer=newsql 网址:http://www.cnblogs.com/mowei/p/ ...
- MySQL concat、concat_ws 和 group_concat 的用法
一.CONCAT()函数CONCAT()函数用于将多个字符串连接成一个字符串.使用数据表Info作为示例,其中SELECT id,name FROM info LIMIT 1;的返回结果为+----+ ...
- Sublime text 3 3103 注册码(2016.2.9更新)
Sublime text 3 (Build 3103) license key,these all tested available on 2016/02/10 .Feel free to enjoy ...
- Git与GitHub同步
如何通过Git Bash实现本地与远端仓库——GitHub的同步 1.下载安装Git:下载网址 2.在自己的github上新建一个repository 例如我这里新建了一个叫test的reposito ...
- upc组队赛6 Greeting Card【打表】
Greeting Card 题目描述 Quido plans to send a New Year greeting to his friend Hugo. He has recently acqui ...