关于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 ...
随机推荐
- 关于MySQL注入漏洞到获取webshell
关于PHP网站报错性注入拿shell的方法,定位到报错在某个字段上的利用方式: 条件1: 爆出了网站的物理路径 条件2:MySQL具有into outfile权限 SQL语句为: 假如字段为2: un ...
- CAS客户端与SpringSecurity集成
4. CAS客户端与SpringSecurity集成 4.1 Spring Security测试工程搭建 (1)建立Maven项目casclient_demo3 ,引入spring依赖和spring ...
- 菜鸟刷面试题(四、Spring/Spring MVC/Spring Boot/Spring Cloud篇)
目录: 为什么要使用 spring? 解释一下什么是 aop? 解释一下什么是 ioc? spring 有哪些主要模块? spring 常用的注入方式有哪些? spring 中的 bean 是线程安全 ...
- 使用 Redis 进行阅读数统计并定时持久化
之前,统计每篇博文的阅读数的方式是经过筛选去重之后直接更新数据库,并发压力直接传导到数据库,假设1秒有1000个并发请求,传统方案会在1秒内并发进行1000次数据库更新操作. 为了降低数据库的并发压力 ...
- Git 在同一台机器上配置多个Git帐号
在同一台机器上配置多个Git帐号 By:授客 QQ:1033553122 实践环境 win10 Git-2.21.0-64-bit.exe TortoiseGit-2.8.0.0-64bit.msi ...
- 利用zabbix API 统计一段时间内监控项的均值和峰值
#coding:utf-8 #给定主机IP获取一段时间内cpu的均值和峰值并写入文件(txt,可以跑完后直接把后缀名改为csv以表格形式打开):需要指定IP文件 import requests imp ...
- English: Class logogram
IT # this is a IT type ISP ANOTHER # following is another logogram LCD PDA
- packstack-ironic
安装openstack Pike版本, 其它版本安装方法类似. centos7.6 packstack目前对NetworkManager 还不支持,我们修改下配置: systemctl disable ...
- Mysql模式匹配两种方法
一.使用LIKE或NOT LIKE比较操作符 使用 "_" 匹配任何单个字符,而 "%" 匹配任意数量的字符(包括零字符): 例如: 1.要想找出以“b”开头的 ...
- Python语法速查: 7. 函数基础
返回目录 (1)函数基本 ● 函数是第一类对象 Python中万物皆对象,所有对象都是第一类的(first class),函数也不例外,也是第一类对象.既然是对象,那就可以当作普通的对象数据处理,比如 ...