JAVA自学笔记23

JAVA自学笔记23

1、多线程
1)引入:
这里写图片描述
2)进程
是正在运行的程序。是系统进行资源分配和调用的独立单位。每一个进程都有它自己的内存空间和系统资源。
多进程:
单进程的计算机只能做一件事情,而现在的计算机都可以做多件事情。CPU在某个时间点上只能做一件事。每一个进程都有它自己的内存空间和系统资源。
3)多线程
-是进程中的单个顺序控制流,是一条执行路径
-一个进程如果只有一条执行路径,则称为单线程程序。一个进程如果有多条执行路径,称为多线程程序。
4)并行与并发
前者是逻辑上同时发生,指在某一个时间段内同时运行多个程序;后者是物理上同时发生,指在,某一个时间点内同时运行多个程序
5)Java程序运行原理
java命令会启动java虚拟机,启动jvm,等于启动了一个应用程序,也就是启动了一个进程,该进程会自动地启动一个“主线程”,然后主线程去调用某个类的main方法,所以main方法运行在主线程中。在此之前的所有程序都是单线程的。

JVM的启动时单线程还是多线程的呢?
多线程的。垃圾回收线程也要先启动,否则很容易出现内容溢出。最少都启动了两个线程。

这里写图片描述
创建新执行线程有两种方法,一种方法时将类声明为Thread的子类。该子类应重写Thread类的run方法。接下来可以分配并启动该子类的实例。
即-自定义一个继承自Thread的类
-重写run()方法(不是类中的所有代码都需要被线程执行。此时,为了区分哪些代码能够被执行。java提供了Thread类中的run()方法用于包含那些被执行的代码。)
-创建对象
-启动线程
另一种方法是声明实现Runnable接口的类,该类然后实现run方法,然后就可以分配该类的实例。start()方法:使该线程开始执行,Java虚拟机调用该线程的run方法。它和run()的区别是run()仅仅是封装被线程执行的代码,直接调用的是普通方法start()首先启动了线程,然后再由jvm去调用该线程的run()方法。

//多线程的实现
//方式1
public class MyThread extends Thread{
public void run(){
//一般来说,被线程执行的代码肯定是比较耗时的
for(int x=0;x<10000;x++){
System.out.println("cc"+x);
}
}
}//测试类
public class MyThreadDemo{
public static void main (String[] args){
//创建线程对象
MyThread my1=new MyThread();
MyThread my2=new MyThread();
//启动线程
my1.start();
my2.start();
}
}

5)获取和设置线程对象的名称
获取:
public final String getName(); //程序将输出Thread-?,?按顺序从0开始

设置
public final void setName(String name);

public class MyThread extends Thread{
//无参构造
public MyThread(){}
//带参构造
public MyThread(String name){
super(name);
}
public void run(){
//一般来说,被线程执行的代码肯定是比较耗时的
for(int x=0;x<10000;x++){
System.out.println("getName()+cc"+x);
}
}
}
//创建线程对象
MyThread my1=new MyThread();
MyThread my2=new MyThread();
//设置名称
my1.setName("cc");
my2.setName("dd");
//启动线程
my1.start();//Thread-0
my2.start();//Thread-1
}
}//带参构造
MyThread my1=new Mythread("许先生");
MyThread my1=new Mythread("刘先生");//获取main方法对应线程的名称
//public static Thread currentThread()
返回当前正在执行的线程对象
System.out.println(Thread currrentThread().getName());

6)线程调度
①分时调度模型:
所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间片
②抢占式调度模型 优先让优先级高的线程使用CPU。如果线程的优先级相同,那么会随机选择一个,优先级高的线程获取的CPU时间片相对多一些。Java使用此类模型

设置优先级的方法:
public final void setPriority (newPriority)
MAX_PRIORITY=10
MIN_PRIORITY=1
NORM_PRIORITY=5

获取线程对象的优先级,默认优先级是5:
public final int getPriority()

public class ThreadPriority extends Thread{
public void run(){
//一般来说,被线程执行的代码肯定是比较耗时的
for(int x=0;x<10000;x++){
System.out.println("getName()+cc"+x);
}
}
}public class ThreadPriorityDemo{
public static void main(String args[]){
ThreadPriority tp1=new ThreadPriority();
ThreadPriority tp2=new ThreadPriority();
ThreadPriority tp3=new ThreadPriority();
tp1.setName("aa");
tp2.setName("bb");
tp3.setName("cc");tp1.getPriority();
tp2.getPriority();
tp3.getPriority()tp1.setPriorty(8);//存在随机性tp1.start();
tp2.start();
tp3.start();
}
}

7)线程控制
线程休眠
public static void sleep(long mills)
在指定毫秒内让当前正在执行的线程休眠
线程加入
public final void join()
等待该线程终止

public class ThreadJoin extends Thread{
public void run(){
for(int x=0;x<10000;x++){
System.out.println("getName()+cc"+x);
}
}
}
public class ThreadJoinDemo{
public static void main(String args[]){
ThreadJoin tp1=new ThreadJoin();
ThreadJoin tp2=new ThreadJoin();
ThreadJoin tp3=new ThreadJoin();
tp1.setName("aa");
tp2.setName("bb");
tp3.setName("cc");tp1.start();
tp1.join();
tp2.start();
tp3.start();
}
}

线程礼让
public static void yield()

public class ThreadJoin extends Thread{
public void run(){
for(int x=0;x<10000;x++){
System.out.println("getName()+cc"+x);
Thread.yield();
}
}
}
public class ThreadYieldDemo{
public static void main(String args[]){
ThreadYield tp1=new ThreadYield();
ThreadYield tp2=new ThreadYield();tp1.setName("aa");
tp2.setName("bb");tp1.start();
tp2.start();}
}

后台线程
public final void setDaemon(boolean on)
将该线程标记为守护线程或用户线程,当正在运行的线程都是守护线程时,jvm退出。必须在启动线程前调用。
这里写图片描述
中断线程
public final void stop()//已过时但仍可使用,具有不安全性
public void interrupt()//把线程状态终止,并抛出InterruptedException 异常

public class ThreadStop extends Thread{
public void run(){
System.out.println("开始执行:"+new Date());
}
} 
public class ThreadStopDemo{
public static void main(String args[]){
ThreadStop ts=new ThreadStop();
ts.start();
Thread.sleep(3000);
//ts.stop();
ts.intereupt();
}
}

8)线程生命周期图解:
这里写图片描述

9)多线程的实现方案2
①好处:可以避免由于java单继承而带来的局限性。适合多个相同程序的代码去处理同一个资源的情况,把线程同程序的代码,数据有效分离,较好地体现; 面向对象的设计思想。
-自定义类MyRunnable实现Runnable接口
-重写run()方法
-创建MyRunnable类的对象
-创建Thread类的对象,作为上一步骤的参数传递

public class MyRunnable implements Runnable{
public void run(){
for(int x=0;x<100){
System.out.println(Thread.currentThread.geiName()+":"+x);
}
}
}
public class MyRunnableDemo{
public static void main(String args[]){
MyRunnable my=new MyRunnable();//Thread t1=new Thread(my,"cc");
//Thread t2=new Thread(my,"dd");
Thread t1=new Thread(my);
Thread t2=new Thread(my);
t1.setName("cc");
t1.setName("dd");
t1.start();
t2.start();
}
}

②两种方式的比较图解
这里写图片描述

@例题1:售卖电影票
这里写图片描述

public class SellTicketDemo{
public static void main(String args[]){
SellTicket st1=new SelTicket();
SellTicket st2=new SelTicket();
SellTicket st3=new SelTicket();st1.setName("窗口1");
st2.setName("窗口2");
st3.setName("窗口3");st1.start();
st2.start();
st3.start();
}
}public class SellTicket extends Thread{
public void run(){
private static int tickets=100;public void run(){
while(true){
if(tickets>0){
System.out.println(getName()+"正在售出第"+(tickets--)+"张票");
}
}
}
}
}
//第二种方式
public class SellTickets implements Runnable{
private int tickets=100;
public void run(){
while(true){
if(tickets>0){
System.out.println(getName()+"正在售出第"+(tickets--)+"张票");
}
}
}
}
public class void main(String args[]){
SellTicket st=new SellTicket();Thread t1=new Thread(st,"窗口1");
Thread t2=new Thread(st,"窗口2");
Thread t1=new Thread(st,"窗口3");t1.start();
t2.start();
t3.start();
}

改进每次售出一张票延迟0.1秒

//第二种方式
public class SellTickets implements Runnable{
private int tickets=100;
//创建锁对象
private Object obj =new Object();
public void run(){
synchronized(obj){
while(true){
if(tickets>0){
Thread.sleep(1000);
System.out.println(getName()+"正在售出第"+(tickets--)+"张票");
}}
}
}
}
public class void main(String args[]){
SellTicket st=new SellTicket();Thread t1=new Thread(st,"窗口1");
Thread t2=new Thread(st,"窗口2");
Thread t1=new Thread(st,"窗口3");t1.start();
t2.start();
t3.start();
}

出现了问题:
①相同号码的票售出多次
②出现了负数序号的票
CPU的每一次执行必须是一个原子性(最简单基本的)操作。是由于随机性和延迟导致的
这里写图片描述

利用同步块的方式解决上述问题
同步代码块:
格式:synchronized(对象)(需要同步的代码;)
可以解决安全问题,其对象可以是任何对象。
把多条语句操作共享数据的部分给包起来
同步的好处与弊端:
好处:同步的出现解决了多线程的安全问题
弊端:当线程相当多时,因为每个线程都会去判断同步上的锁,非常耗费系统资源
前提:多个线程使用同一把锁
同步方法:把同步关键字加载到方法上
A:同步代码块的锁对象是谁呢?
* 任意对象。
*
* B:同步方法的格式及锁对象问题?
* 把同步关键字加在方法上。
*
* 同步方法是谁呢?
* this
*
* C:静态方法及锁对象问题?
* 静态方法的锁对象是谁呢?
* 类的字节码文件对象。(反射会讲)

//再次改进
public class SellTicketDemo {public static void main(String[] args) {// 创建资源对象SellTicket st = new SellTicket();// 创建三个线程对象Thread t1 = new Thread(st, "窗口1");Thread t2 = new Thread(st, "窗口2");Thread t3 = new Thread(st, "窗口3");// 启动线程t1.start();t2.start();t3.start();}
}
package cn.itcast_11;public class SellTicket implements Runnable {// 定义100张票private static int tickets = 100;// 定义同一把锁private Object obj = new Object();private Demo d = new Demo();private int x = 0;@Overridepublic void run() {while (true) {if(x%2==0){synchronized (SellTicket.class) {if (tickets > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+ "正在出售第" + (tickets--) + "张票 ");}}}else {private static synchronized void sellTicket() {if (tickets > 0) {try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+ "正在出售第" + (tickets--) + "张票 ");}
}
}

8)线程安全的类
StringBuffered
Vector
Hashtable
collections下有很多线程安全的类

转载于:https://www.cnblogs.com/Tanqurey/p/10485332.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/465135.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

上午写了一段代码,下午就被开除了~

俗话说得好&#xff0c;“代码写的少&#xff0c;离职少不了”。最近畅游互联网&#xff0c;发现一些离职小技巧&#xff0c;读后&#xff0c;内心被深深地打动了……但是&#xff0c;细细品过之后&#xff0c;发现对我们程序员不太适用了。例如&#xff1a;领导夹菜你转桌&…

nginx加载html目录下图片,nginx配置访问图片路径以及html静态页面的调取方法

nginx配置访问图片路径以及html静态页面的调取方法发布时间&#xff1a;2017-03-09 12:06来源&#xff1a;互联网当前栏目&#xff1a;web技术类给大家讲一个快速配置nginx访问图片地址&#xff0c;以及访问html静态页面的配置。1.实验环境首先随便某个路径下创建相应的目录。如…

微信小程序继续入坑指南

微信小程序继续入坑指南 wxml 类似于html 感觉和ejs灰常的相似 数据绑定 js Page({data: {message: "hello world"} })wxml <view>{{message}}</view> 使用的是https://mustache.github.io/模板引擎系统 对组件的属性和控制属性的更改 <view id"…

思科收购网络安全管理厂商Pari Networks

思科收购网络安全管理厂商Pari Networkshttp://netsecurity.51cto.com 2011-01-28 09:39 胡杨 译 网界网 我要评论(0)摘要&#xff1a;思科本星期宣布&#xff0c;它打算收购私营企业Pari Networks。这个企业是前思科工程师创建的&#xff0c;主要提供网络配置、变更和合规…

20年软件工程师的经验

软件工程师在做设计的时候&#xff0c;一定要有设计的思维&#xff0c;码农如果只是砌砖的&#xff0c;那么他的可替代性和技能能力并不高。前段时间看到一个设计师傅&#xff0c;在很狭小的空间内设计了非常非常不错的室内设计&#xff0c;利用了每一个可以利用的地方。如果我…

html超市代码,前端 CSS : 5# 纯 CSS 实现24小时超市

介绍原文链接感謝 comehope 大佬的 [前端每日实战]效果预览源代码地址代码解读1. html 结构命名规则使用了 BEM常规样式初始化* {margin: 0;padding: 0;box-sizing: border-box;}body {height: 100vh;overflow: hidden;}2. 街道背景街道背景分为两部分深蓝色的天空.street {hei…

送30块树莓派PICO 开发板!

大家好&#xff0c;今天是周日&#xff0c;给大家搞个小抽奖&#xff0c;送30块。嵌入式猛男必备&#xff0c;学嵌入式看『我要学嵌入式』&#xff0c;知识持久有力。点击关注&#xff0c;回复【1031】参与抽奖&#xff0c;免费送 10块 树莓派最新PICO开发板。学C语言看『写代码…

嘉立创又搞大事情了,与你我相关!

你们一定不知道嘉立创最近又悄咪咪的做了一件大事儿&#xff0c;硬创社硬件项目共享平台上线公测啦&#xff0c;这是一个帮助电子工程师实现技术变现的平台&#xff0c;平台刚刚上线公测&#xff0c;前期还在邀请电子工程师填充内容阶段&#xff0c;即日起平台每上传一个项目就…

c html联调,JS与native 交互简单应用

JS与native 交互简单应用一、objectiveC 语法简介二、简易项目浏览器搭建新建项目步骤&#xff1a;1>DraggedImage.png2>2222.png3>33333.png4>4444.png建立一个小的浏览器即webview关键代码如下&#xff1a;// context 上下文也可以在此处获取&#xff0c;开始加载…

写给我弟

我堂弟今年24岁&#xff0c;也是我最小的一个堂弟&#xff0c;我想给他说点事&#xff0c;想告诉他一些东西&#xff0c;但是也担心自己所说的&#xff0c;并不能让他认同和接受。我心里一定是有我弟的&#xff0c;也是装着我弟的&#xff0c;所以我弟的事情&#xff0c;我自己…

Chrome插件(扩展)

【干货】Chrome插件(扩展)开发全攻略 写在前面 我花了将近一个多月的时间断断续续写下这篇博文&#xff0c;并精心写下完整demo&#xff0c;写博客的辛苦大家懂的&#xff0c;所以转载务必保留出处。本文所有涉及到的大部分代码均在这个demo里面&#xff1a;https://github.com…

Apache OpenJPA 2.1.0 发布

OpenJPA 是 Apache 组织提供的开源项目&#xff0c;它实现了 EJB 3.0 中的 JPA 标准&#xff0c;为开发者提供功能强大、使用简单的持久化数据管理框架。OpenJPA 封装了和关系型数据库交互的操作&#xff0c;让开发者把注意力集中在编写业务逻辑上。OpenJPA 可以作为独立的持久…

手把手带你写一个中断输入设备驱动

今天群里有人问&#xff0c;要开始驱动开发的话从什么开始比较好。我说&#xff0c;应该开始去摸索触摸屏驱动&#xff0c;现在我想了下&#xff0c;触摸屏驱动可能会难了些&#xff0c;但是从一个GPIO开始&#xff0c;我觉得一定是一件很容易的事情。所以这篇文章就来了。大家…

驱动调试神器printk你掌握了吗?

[导读] 刚刚开始做Linux相关开发工作时&#xff0c;深感Linux内核代码庞大&#xff0c;要加些自己的驱动进内核代码树&#xff0c;常常深陷bug的泥沼难以自拔&#xff0c;今天来分享一下内核调试利器printk的使用心得。前面一段时间很忙&#xff0c;后期更文频率会渐渐回归正常…

腾讯云技术专家卢萌凯手把手教你Demo一个人脸识别程序!

欢迎大家前往腾讯云社区&#xff0c;获取更多腾讯海量技术实践干货哦~ 本文来自腾讯云技术沙龙&#xff0c;本次沙龙主题为Serverless架构开发与SCF部署实践 卢萌凯&#xff1a;毕业于东南大学&#xff0c;曾就职于华为&#xff0c;熟悉云行业解决方案。目前负责腾讯云中间件产…

二十世纪最伟大的算法,你了解哪个?

导读&#xff1a;作者July总结了一篇关于计算方法的文章《 细数二十世纪最伟大的10大算法 》。一、1946 蒙特卡洛方法[1946: John von Neumann, Stan Ulam, and Nick Metropolis, all at the Los Alamos Scientific Laboratory, cook up the Metropolis algorithm, also known …

桌面计算机恢复出厂设置,windows7电脑怎么恢复出厂设置

我们使用电脑一段时间&#xff0c;由于各种问题&#xff0c;希望将电脑恢复出厂设置&#xff0c;那么windows7电脑怎么恢复出厂设置呢&#xff1f;下面跟着学习啦小编来一起了解下windows7电脑恢复出厂设置的方法吧。windows7电脑恢复出厂设置方法一按下开机键&#xff0c;启动…

关于Exchange管理控制台报“您的权限不足,无法此查看数据”的解决办法

今天朋友突然来电话&#xff0c;说自己的Exchange 2010 EMC突然报“you dont have sufficient permissions to view this data”&#xff08;您的权限不足&#xff0c;无法查看此数据&#xff09;&#xff0c;同时所有的cmdlet命令也不可以执行。询问我解决办法&#xff0c;出错…

内存为什么还有管理?

本文作者&#xff1a;度白嵌入式任何程序运行起来都需要分配内存空间存放该进程的资源信息的&#xff0c;C程序也不例外。C程序中的变量、常量、函数、代码等等的信息所存放的区域都有所不同&#xff0c;不同的区域又有不同的特性。C语言学习者、尤其是在学习嵌入式的朋友&…

旧手机别扔,手把手教你DIY一台Linux服务器

作者&#xff1a;Hannah Lee编译&#xff1a;弯月 欧阳姝黎来源&#xff1a;CSDN&#xff08;ID&#xff1a;CSDNnews&#xff09;本文将向你展示如何使用 UrBackup 和 Linux Deploy在一台 Android 旧手机上搭建一台备份服务器。旧手机的污染问题众所周知&#xff0c;我有一台旧…