关于Java的多线程Runnable的个人理解(基础,不讲概念)
背景说明:
在学了Java的多线程(继承Thread,Runnable)以后,我出于好奇,就想知道java到底是不是多线程的,不能它说自己是多线程就是多线程,自己想验证一下,于是我就想测试一下,但继承Thread由于java的单继承形式,导致不能生成多线程,但是Runnable可以,于是我就做了一个脚本(个人感觉一个java文件就是一个脚本,没有上升到项目级别),我同时生成了10个线程,来模拟购票系统,假设一个线程模拟一个人去购10张票,一个人购买一张票的时间是0.5s(不可同时去购买两张票及以上),然后观察这100张票用多少时间购买完成。
所遇到的问题1:
问题描述:
首先就是计算一共用了多少时间了,我利用了如下图的代码框架来编写,发现一个问题:因为当前java主程序也是一个线程,当主java程序在运行时,在创建完这10个线程后,主Java程序就执行完成了,它不会管这10个线程是否运行完成,在时间计算时,出现了问题。总时间会在线程运行时输出(输出的时间不是线程运行的时间)
解决步骤1:
解决方案如图,解释一下:我在接口实现类中定义了一个线程静态共享变量,这个时候,当10个线程创建成功并运行,在最后一个线程运行完毕是对endTIme进行最后一次修改,该endTime就是这十个线程最后运行完成的时间,再进行时间计算。问题也就来了,还是没有解决时间的统计,因为java主程序还是一个线程,时间输出错误。
解决步骤2:
考虑到java主程序也是一个线程,我在创建10个线程后,立即休眠java 主线程(提前预估时间并设置相应的休眠时间),休眠时间稍微比线程运算预估时间大一点
最后:
时间问题解决,但是这个时候引发了一个大的问题,当10个线程在访问同一个数据并修改时,数据可能发生异常。这个时候就需要线程对数据的互斥机制。
代码:
主程序java代码:javaThreadTest
package org.axc.com.javathread;
import java.util.Scanner;
/**
*
* @ClassName: javaThreadTest
* @Description: 测试java线程的运行
* @author Anxc
* @date 2019年8月8日
*
*/
public class JavaThreadTest {
public static void main(String[] args) {
// 线程的创建
MyThread mythread;
System.out.println("---------继承Thread方式来实现创建线程-----------------");
Scanner in = new Scanner(System.in);
String menu="线程测试开始";
int chioce=1;
while(chioce!=0) {
mythread = new MyThread();
System.out.println("请输入非0来开始调试继承的Thread");
System.out.print(">>");
chioce = in.nextInt();
if(chioce==0) {
System.out.println("ByeBye");
break;
}
// 输出菜单
System.out.println(menu);
// 线程运行
mythread.start();
}
System.out.println("------------利用Runnable接口实现创建线程-------------");
// 测试Runnable的多线程所用时间
chioce = 1;
// 利用Runnable接口,初始化线程
Runnable runnable = new MyRunnable();
long startTime;
long endTime;
while(chioce!=0) {
System.out.println("请输入非0来开始调试");
System.out.print(">>");
chioce = in.nextInt();
if(chioce == 0) {
System.out.println("Runnable ByeBye!");
break;
}
startTime = System.currentTimeMillis();
System.out.println(startTime);
// 创建10个线程来观察是否是真的多线程运行
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
new Thread(runnable).start();
Thread t=new Thread(runnable);
//t.isAlive();//判断线程是否存活
try {
Thread.sleep(8000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
// 输出最后所用时间
System.out.println("最终所用时间为:"+(((MyRunnable) runnable).getEndTime()-startTime));
}
}
}
实现接口Runnable的java程序代码:MyRunnable
package org.axc.com.javathread;
/**
*
* @ClassName: MyRunnable
* @Description: 测试Runnable的真正多线程
* @author Anxc
* @date 2019年8月8日
*
*/
public class MyRunnable implements Runnable {
private static int count=100; //加互斥锁,当一个线程去修改值时,其它线程不能读取
public static long endTime;
private static boolean flag=true;
public MyRunnable() {
}
@Override
public void run() {
int num=10;
// 加锁,使修改变量时只有一个线程在操作
while(num>0) {
if(flag) {
flag=false;//加锁
count--;
// TODO Auto-generated method stub
System.out.println("当前剩余"+count);
flag=true;//关锁
}
else {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
continue;
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
num--;
}
// 获取线程运行终止时间
endTime = System.currentTimeMillis();
// System.out.println(endTime);
}
public long getEndTime() {
return endTime;
}
}
继承Thread的方法的java程序:MyThread
package org.axc.com.javathread;
/**
*
* @ClassName: MyThread
* @Description: java线程的实现方式之一继承Thread
* @author Anxc
* @date 2019年8月8日
*
*/
public class MyThread extends Thread {
private static int count = 0;
public void run() {
int num=0;
count++;
while(num<5) {
System.out.println("再等等!"+count+num);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
num++;
}
System.out.println("当前已经累计运行该线程:"+count+"次");
}
}
关于Java的多线程Runnable的个人理解(基础,不讲概念)的更多相关文章
- JAVA与多线程开发(线程基础、继承Thread类来定义自己的线程、实现Runnable接口来解决单继承局限性、控制多线程程并发)
实现线程并发有两种方式:1)继承Thread类:2)实现Runnable接口. 线程基础 1)程序.进程.线程:并行.并发. 2)线程生命周期:创建状态(new一个线程对象).就绪状态(调用该对象的s ...
- Java Tread多线程(1)实现Runnable接口
作者 : 卿笃军 原文地址:http://blog.csdn.net/qingdujun/article/details/39347245 本文演示,Tread多线程实现Runnable接口,以及简单 ...
- java之多线程 二
线程的生命周期: 当线程被创建并被启动时,它既不是一启动就进入了执行状态,在线程的生命周期中,它要经过new(新建),就绪(Runnable),运行(Running),阻塞(Blocked),dead ...
- JAVA之多线程的创建
转载请注明源出处:http://www.cnblogs.com/lighten/p/5967853.html 1.概念 老调重弹,学习线程的时候总会牵扯到进程的概念,会对二者做一个区分.网上有较多的解 ...
- Java的多线程(上)
多线程的优点和必要性是不言而喻的. 三种方法实现多线程 1. 继承Thread class A extends Thread{ public void run() {...} } 使用时, new A ...
- JAVA之多线程概念及其几种实现方法优劣分析
1. 多线程 程序:指令集,静态的概念 进程:操作系统调动程序,是程序的一次动态执行过程,动态的概念 线程:在进程内的多条执行路径 Ps:单核的话进程都是虚拟模拟出来的,多核处理器才可以执行真正的多线 ...
- Java线程锁&分布式锁的理解及应用
了解Java线程锁之前,先理解线程和进程的定义.进程是操作系统分配资源(CPU)的基本单位,线程是CPU执行的基本单位,一个进程可拥有多个线程,同进程间的多个线程共享分配给进程的资源.比如启动JVM时 ...
- Java学习---多线程的学习
基础知识 每个正在系统上运行的程序都是一个进程(process).每个进程包含一到多个线程(thread).进程也可能是整个程序或者是部分程序的动态执行. 线程是一组指令的集合,或者是程序的特殊段,它 ...
- 沉淀再出发:再谈java的多线程机制
沉淀再出发:再谈java的多线程机制 一.前言 自从我们学习了操作系统之后,对于其中的线程和进程就有了非常深刻的理解,但是,我们可能在C,C++语言之中尝试过这些机制,并且做过相应的实验,但是对于ja ...
随机推荐
- 如何快速将多个excel表格的所有sheet合并到一个sheet中
1.将需要合并的excel文件放在同一个文件夹下: 2.新建一个excel表格并打开,右键sheet1,查看代码,然后复制下方的代码到代码框里,点击菜单栏中的“运行”–“运行子过程/用户窗体”,等待程 ...
- Java中往zip压缩包追加文件
有个需求,从某个接口下载的一个zip压缩包,往里面添加一个说明文件.搜索了一下,没有找到往zip直接添加文件的方法,最终解决方法是先解压.再压缩. 具体过程如下: 1.一个zip文件的压缩和解压工具类 ...
- TP5 try{}catch{}异常捕获不到 解决办法
问题:TP5用下面的方法, 想要获取抛出的异常捕获不到…… 错误的写法: try{ …… } catch (Exception $e) { echo $e->getMessage(); } 正确 ...
- 部署flas到服务器:No module named flask
首先,你要先把nginx和uwsgi安装好(个人觉得这搭起来比较舒服),可以通过pip 或者源安装,具体方法在前面我有提到过,好了接下来我就讲讲我的踩坑经历与解决办法. 我先采用的pip insta ...
- SpringSession 独立使用
疯狂创客圈 Java 高并发[ 亿级流量聊天室实战]实战系列 [博客园总入口 ] 架构师成长+面试必备之 高并发基础书籍 [Netty Zookeeper Redis 高并发实战 ] 前言 Crazy ...
- 如何实现一台服务器同时运行两个php版本
有需要学习交流的友人请加入交流群的咱们一起,有问题一起交流,一起进步!前提是你是学技术的.感谢阅读! 点此加入该群jq.qq.com 假设您已经安装了Apache,为这两个项目创建了虚拟主机,并添加 ...
- 一道ctf-内存取证volatility的学习使用
环境:kali 0x00 volatility官方文档 https://github.com/volatilityfoundation/volatility 在分析之前,需要先判断当前的镜像信息,分析 ...
- 精通awk系列(5):BEGIN和END语句块
回到: Linux系列文章 Shell系列文章 Awk系列文章 BEGIN和END语句块 awk的所有代码(目前这么认为)都是写在语句块中的. 例如: awk '{print $0}' a.txt a ...
- K8S 1.16 [plugin flannel does not support config version
[plugin flannel does not support config version 导致 Unable to update cni config: no valid networks fo ...
- Lucene&Solr框架之第一篇
2.信息检索 信息检索是计算机世界中非常重要的一种功能.信息检索不仅仅是指从数据库检索数据,还包括从文件.网页.邮件.用户手输入的内容中检索数据.通过怎样的高效方式将用户想要的信息快速提取出来,是计算 ...


