毕向东java视频学习笔记day11-day13多线程

ACMer_Shadow ACMer_Shadow     2022-07-31     329

关键词:

Java_Day12 多线程01

进程:正在进行中的程序(直译).

线程:就是进程中一个负责程序执行的控制单元(执行路径)

一个进程中可以多执行路径,称之为多线程。

一个进程中至少要有一个线程。

开启多个线程是为了同时运行多部分代码。

每一个线程都有自己运行的内容。这个内容可以称为线程要执行的任务。


多线程好处:解决了多部分同时运行的问题。

多线程的弊端:线程太多回到效率的降低。

其实应用程序的执行都是cpu在做着快速的切换完成的。这个切换是随机的。

JVM启动时就启动了多个线程,至少有两个线程可以分析的出来。

1,执行main函数的线程,

该线程的任务代码都定义在main函数中。

2,负责垃圾回收的线程。

 

主线程结束了,JVM就结束了是错误的想法。还有别的线程在进行,所有的线程结束了,JVM才结束了。

 

电脑中CPU一次只能运行一个线程,但是他在多个线程中不断快速切换,让人们感觉到可以多个线程同时运行。

如何创建一个线程呢?

创建线程方式一:继承Thread类。

步骤:

1,定义一个类继承Thread类。

2,覆盖Thread类中的run方法。

3,直接创建Thread的子类对象创建线程。

4,调用start方法开启线程并调用线程的任务run方法执行。

可以通过ThreadgetName获取线程的名称 Thread-编号(0开始)

(当线程对象创建时,就已经进行了编号,并且已经创建了线程,但是没有开始运行线程)

主线程的名字就是main

创建线程的目的是为了开启一条执行路径,去运行指定的代码和其他代码实现同时运行。

而运行的指定代码就是这个执行路径的任务。

jvm创建的主线程的任务都定义在了主函数中。

而自定义的线程它的任务在哪儿呢?

Thread类用于描述线程,线程是需要任务的。所以Thread类也对任务的描述。

这个任务就通过Thread类中的run方法来体现。也就是说,run方法就是封装自定义线程运行任务的函数。

run方法中定义就是线程要运行的任务代码。

开启线程是为了运行指定代码,所以只有继承Thread类,并复写run方法。

将运行的代码定义在run方法中即可。

如果25行改成d1.run(),虽然有了线程,但是JVM把他当做一个普通的run方法执行,只有一个main主线程,并没有运行多线程,改成d1.start()之后,多线程才开始运行


Thread.currentThread() --->>当前线程


本来栈内存中只有一列,多线程后,有好几列

Java_Day13 多线程02

CPU执行资格:可以被CPU处理,在处理队列中排队

CPU执行权  :正在被CPU处理


创建线程的第一种方式:继承Thread类。

 

 

<pre name="code" class="cpp">第一种方法原理:
class Thread //Thread源代码内容
{
	private Runnable r;
	Thread(){   //无参构造函数
	}
	Thread(Runnable r){//有参构造函数
		this.r  = r;
	}
	public void run(){//创建
		if(r!=null)
			r.run();
	}
	public void start(){//线程开始
		run();
	}
}

class SubThread extends Thread{   //第一种方法继承Thread
	public void run(){
		System.out.println("hahah");
	}
}
{  //main函数内容
SubThread s = new SubThread();  //创建无参的thread类对象
s.start();
}


 

创建线程的第二种方式:实现Runnable接口。

1,定义类实现Runnable接口。

2,覆盖接口中的run方法,将线程的任务代码封装到run方法中。

3,通过Thread类创建线程对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。

为什么?因为线程的任务都封装在Runnable接口子类对象的run方法中。

所以要在线程对象创建时就必须明确要运行的任务。

4,调用线程对象的start方法开启线程。

package day12;
class Demo2 implements Runnable //准备扩展Demo类的功能,让其中的内容可以作为线程的任务执行。
// 通过接口的形式完成。
{
	public void run() {
		show();
	}
	public void show() {
		for (int x = 0; x < 20; x++) {
			System.out.println(Thread.currentThread().getName() + "....." + x);
		}
	}
}
public class ThreadDemo {
	public static void main(String[] args) {
		Demo2 d = new Demo2();
		
		Thread t1 = new Thread(d);//如果是new thread(); thread会运行他自己的线程,不是我们的d线程
		Thread t2 = new Thread(d);
		t1.start();
		t2.start();
	}
}

.10第二种方法和第一种方法的原理

 

class Thread //Thread源代码内容
{
	private Runnable r;
	Thread(){   //无参构造函数
	}
	Thread(Runnable r){//有参构造函数
		this.r  = r;
	}
	public void run(){//创建
		if(r!=null)
			r.run();
	}
	public void start(){//线程开始
		run();
	}
}
class ThreadImpl implements Runnable{
	public void run(){
		System.out.println("runnable run");
	}
}
{    //main主函数内容
ThreadImpl i = new ThreadImpl();
Thread t = new Thread(i);//有参的thread
t.start();
}

.11第二种方法的好处

Runnable

就是一种将线程任务进行封装

实现Runnable接口的好处:

1,将线程的任务从线程的子类中分离出来,进行了单独的封装。

按照面向对象的思想将任务的封装成对象。

2,避免了java单继承的局限性。

所以,创建线程的第二种方式较为常用。

 

第一种的局限性:

如果这个类本身是一个Zi子类,已经继承了父类Fu,再继承Thread变成多继承,这是JAVA不允许的,所以第一种方法有局限性。

 

.12买票系统

 

.13-多线程(线程安全问题的现象)

.14-多线程(线程安全问题产生的原因)

 

线程安全问题产生的原因:

1,多个线程在操作共享的数据。

2,操作共享数据的线程代码有多条。

当一个线程在执行操作共享数据的多条代码过程中,其他线程参与了运算。

就会导致线程安全问题的产生。

 

 

.15-多线程(同步代码块)LOCK同步锁)

解决思路;

就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,

其他线程时不可以参与运算的。

必须要当前线程把这些代码都执行完毕后,其他线程才可以参与运算。

 

java中,用同步代码块就可以解决这个问题。

同步代码块的格式:

synchronized(对象)  任意一个对象,但是一定要一个

{

需要被同步的代码 ;

}

 

class Ticket implements Runnable//extends Thread
{
	private  int num = 100;
	Object obj = new Object();
	public void run()
	{
		while(true)
		{
			synchronized(obj)
			{
				if(num>0)
				{
					try{Thread.sleep(10);}catch (InterruptedException e){}
					System.out.println(Thread.currentThread().getName()
							+".....sale...."+num--);
				}
			}
		}
	}
}

同步的好处:解决了线程的安全问题。

同步的弊端:相对降低了效率,因为同步外的线程的都会判断同步锁。

同步的前提:同步中必须有多个线程并使用同一个锁。

 

.18同步函数

public synchronized void add(int num)//同步函数
{
		sum = sum + num;
		try{Thread.sleep(10);}catch(InterruptedException e){}
		System.out.println("sum="+sum);
}

同步函数的锁是this

同步函数和同步代码块的区别:

同步函数的锁是固定的this

同步代码块的锁是任意的对象。

 

建议使用同步代码块。因为用this就固定了锁,没有灵活性。

 

. 20-多线程(验证静态同步函数的锁)

静态的同步函数使用的锁是  该函数所属字节码文件对象

可以用 getClass方法获取,也可以用当前  类名.class 表示。

.21多线程下的单例模式

详见我的博客 http://blog.csdn.net/qq_24653023/article/details/51706972

Java_Day14 多线程03

等待/唤醒机制。

涉及的方法:

1wait(): 让线程处于冻结状态,被wait的线程会被存储到线程池中。

2notify():唤醒线程池中一个线程(任意).

3notifyAll():唤醒线程池中的所有线程。


这些方法都必须定义在同步中。

因为这些方法是用于操作线程状态的方法。

必须要明确到底操作的是哪个锁上的线程。


为什么操作线程的方法wait notify notifyAll定义在了Object类中?

因为这些方法是监视器的方法。监视器其实就是锁。

锁可以是任意的对象,任意的对象调用的方式一定定义在Object类中。

notify:只能唤醒一个线程,如果本方唤醒了本方,没有意义。而且while判断标记+notify会导致死锁。

notifyAll解决了本方线程一定会唤醒对方线程的问题。

多线程(基于毕向东视频)

进程:是一个正在执行的程序 每一个进程执行都有一个执行顺序,该顺序是一个执行路径,或者叫一个控制单元。 线程:就是进程中一个独立的控制单元。 线程在控制着进程的执行。 一个进程中至少有一个线程。java虚... 查看详情

致敬毕向东java视频

大一:转专业之前在网易云公开课看过麻省理工的线代收益颇多,大二上学期:在网易云上看了阿发的c,反复看了五六遍,感觉不难又总感觉少点什么,后来看了好斌(优秀的专科老师)豁然开朗,看了两遍。好斌的数据结构... 查看详情

毕向东—java基础知识总结(超级经典)

  Java基础知识总结(超级经典)  写代码:    1,明确需求。我要做什么?    2,分析思路。我要怎么做?1,2,3。    3,确定步骤。每一个思路部分用到哪些语句,方法,和对象。    4,代码实现... 查看详情

毕向东java基础教程

人机交互方式:图形化界面(GraphicalUserInterface:GUI)命令行方式(CommandLineInterface:CLI)  查看详情

day13java第十三天i/o学习笔记

行分割符在java中可以通过方法得到.系统属性名是line.separator.不同平台的行分隔符是不同的。windows7: macOS : -------------------------------- System.getProperty("line.separator"); //执行系统属性名/FileWriter:没有缓冲区功能------------------------ 查看详情

日撸java三百行day11-13(代码片段)

...2.链表的插入删除3.代码说明闵老师的文章链接:日撸Java三百行(总述)_minfanphd的博客-CSDN博客自己也把手敲的代码放在了github上维护:https://github.com/fulisha-ok/sampledataday11-day12顺序表1.面向过程面向对象区别面向过... 查看详情

毕向东java基础总结(代码片段)

Java基础知识总结(超级经典)写代码:1,明确需求。我要做什么?2,分析思路。我要怎么做?1,2,3。3,确定步骤。每一个思路部分用到哪些语句,方法,和对象。4,代码实现。用具体的java语言代码把思路体现出来。 学习... 查看详情

java学习笔记day_01

...劲,但会一点一点变好的。本笔记是以我按照传智播客的视频和Java核心思想来学习,前面的基础部分主要是用于个人的复习使用的。第一段代码:HelloWorldpublicclassHelloWorld{publicstaticvoidmain(String[]args){System.out.prin 查看详情

[java视频笔记]day25(代码片段)

正则表达式:符合一定规则的表达式。        作用:用于专门操作字符串。        特点:用于一些特定的符号来表示一些代码操作,这样就简化了书写。        所以学习正则表达式,就是在学... 查看详情

视频学习记录day13

LANP环境工作原理: 老男孩以这个为准1、安装mysqlmkdir-p/home/oldboy/toolscd/home/oldboy/toolstar-xfmysql-5.5.56-linux-glibc2.5-x86_64.tar.gzmvmysql-5.5.56-linux-glibc2.5-x86_64/application/mysql-5.5.56ln-s/applicat 查看详情

day2java学习笔记

1.JDK7新特性   利用下划线_去分割数字,可以方便看清多位数字2.变量,其本质是程序中最基本的存储单元   typevarName[=value]3.可以一行声明多个变量,但最好一行一个4.局部变量localvariable   在方法... 查看详情

《30天自制操作系统》13_day_学习笔记

harib10a:  简化字符串的显示:我们发现字符串显示三条语句总是重复出现,并且总是一起出现的。接下来我们把它归纳到一个函数中,这样便于使用。x,y--位置的坐标  c--字符颜色 (color)  b--背景颜色 ... 查看详情

java后端开发工程师学习笔记狂神说java笔记

目录1.学习视频推荐阶段一1.计算机基础2.Java入门学习3.java基础语法4.流程控制5.方法6.数组7.面向对象编程8.异常9.常用类10.集合框架11.IO流12.多线程13.GUI编程14.网络编程15.注解和反射16.JUC编程17.JVM探究阶段二阶段三阶段四阶段五阶... 查看详情

java基础学习笔记day01

      java基础学习笔记day011.软件开发:  软件:按照特定顺序组织的计算机数据和指令的集合  开发:软件的制作过程  软件开发:借助开发工具和计算机语言制作软件2.java概述:  java之父:詹姆斯·高斯林 ... 查看详情

java求助:如何建立一个树形结构

在Java中如何实现一个如下的树形结构:root/|\year_2009year_2008year_2007,etc/|||month_1month_2month_1month_1|\|/\|day1day2day1day1day2day1其中day1是一个字符串,我用一个例子来说明我的意图:我得到一个字符串,“1992-12-21|1223.3”,我想将... 查看详情

python学习笔记-day-8(代码片段)

本节内容Socket介绍Socket参数介绍基本Socket实例Socket实现多连接处理通过Socket实现简单SSH通过Socket实现文件传送作业:开发一个支持多用户在线的FTP程序  1.Socket介绍概念A networksocket isanendpointofaconnectionacrossa comput... 查看详情

day13笔记

1:StringBuffer(掌握) (1)用字符串做拼接,比较耗时并且也耗内存,而这种拼接操作又是比较常见的,为了解决这个问题,Java就提供了 一个字符串缓冲区类。StringBuffer供我们使用。 (2)StringBuffer的构造方法 A:StringBuffer() B:StringBuffer(in... 查看详情

java学习笔记---day1

💕前言:作者是一名正在学习JAVA的初学者,每天分享自己的学习笔记,希望能和大家一起进步成长💕目录💕前言:作者是一名正在学习JAVA的初学者,每天分享自己的学习笔记,希望能和大家... 查看详情