Java多线程:

进程:进行中的程序

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

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

一个进程至少一个线程

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

每个线程都有自己运行的内容,这个内容成为线程要执行的任务

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

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

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

JVM启动时就启动了多个线程,至少有两个线程

1.执行main函数的线程

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

2.负责垃圾回收的线程

如何创建一个线程:

方式一:继承Thread类

步骤:

1.创建一个类继承Thread类

2.重写Thread的run方法//重写run方法

3.直接创建Thread类的子类对象C创建线程

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

class Demo extends Thread

{

private String name = "弟鸽";

Demo(String name)

{

super(name);

//this.name = name;

}

public void run(){

for(int i=1;i<10;i++)

{

for(long j= -199999999;j<199999999;j++){ }

system.out.println(name+"*****"+i+"--------"

+Thread.currentThread().getName());

}

}

}

main(){

Demo d1 = new Demo("脔割");

Demo d2 = new Demo("儿纸");

//d1.run();

//d2.run();

d1.start();

d2.start();

}

可以通过Thread的getName获取线程的名称 Thread—(0开始)

主线程的名称是 main

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

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

JV创建的主线程的任务都定义在主函数里

自定义的线程的任务在run方法里;

Thread类用于描述线程,线程是 需要任务的,所以Thread类也对任务的描述,这个任务就通过Thread类中的run方法实现。也就是说,run方法就是封装自定义线程运行任务的函数。

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

开启线程是为了运行指定代码,所以只有继承Thread类,并复写run方法,将要运行的代码定义在run方法中即可。

run()和start()的区别:

1.start()可以启动一个新的线程

2.start()不能重复调用run()可以

3.start()中的run()代码可以不执行完就继续执行下面的代码,即进行了线程切换。直接调用run()方法必须等待其代码全部执行完才能继续执行下面的代码

4.start()实现了多线程,run()没有实现多线程

临时阻塞状态 具备执行资格但不具备执行权 正在等待执行权

↑  ↑

↓                      ↑

进程--->start()--->运行--->sleep(time)--->冻结//释放执行权的同时

| --->  wait()  --->↑  释放执行资格

stop()

|

消亡

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

cpu的执行权: 正在被cpu处理

创建线程的第二种方法:

1.定义类实现Runnable接口

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

3.通过Tread类创建对象,并将Runnable接口的子类对象作为Thread类的构造函数的参数进行传递。(原因是线程任务都封装在Runnable接口子类对象的run方法中,所以在线程对象创建时就得明确要运行的任务。)

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

class Demo2 implements Runnable //准备扩展Demo2类的功能,让其中的内容作为线程的任务执行

//通过接口的形式完成

{

public void run()

{

show();

}

public void show(){

for(int i=1;i<10;i++)

{

for(long j= -199999999;j<199999999;j++){}

System.out.println(Thread.currentThread().getName());

}

}

}

main()

{

Demo2 d3 = new Demo2();

Thread t1 = new Thread(d3,"办证");

Thread t2 = new Thread(d3,"学妹介绍Q");

t1.start();

t2.start();

}

Runnable接口:将线程的任务进行了对象的封装

实现Runnable接口的好处:

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

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

2.避免了Java单继承的局限性

故较为常用的是实现Runnable

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

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

2.操作共享数据的代码有多条

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

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

解决思路:

就是将多条操作共享数据的线程代码封装起来,当有线程在执行这些代码的时候,必须要当成线程把这些代码都执行完毕后,其他线程才可以  ------->局部代码块

在Java中用同步代码块就可以解决这个问题

synchronized(对象)

{

局部代码;

}

同步的好处:

解决了线程的安全问题

同步的弊端:

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

同步的前提:

同步中必须有多个线程吗,并使用同一个锁。

同步函数的锁是this

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

1.同步函数的锁是固定的this

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

建议使用同步代码块

当同步函数为static时,锁为this.getClass()即该函数所属字节码文件对象,可用getClass()方法获取,也可以用当前

类名.class 表示。

死锁:

class DeadLockTestDemo implements Runnable

{

private boolean flag;

DeadLockTestDemo(boolean flag)

{

this.flag = flag;

}

public void run()

{

if(flag)

{

while(true)

synchronized(MyLock.lockA)

{

System.out.println(Thread.currentThread().getName()+"--If--->LockA");

synchronized(MyLock.lockB)

{

System.out.println(Thread.currentThread().getName()+"--If--->LockB");

}

}

}

else

{

while(true)

synchronized(MyLock.lockB)

{

System.out.println(Thread.currentThread().getName()+"--Else--->LockB");

synchronized(MyLock.lockA)

{

System.out.println(Thread.currentThread().getName()+"--Else--->LockA");

}

}

}

}

}

class MyLock

{

public static final Object lockA = new Object();

public static final Object lockB = new Object();

}

public class DeakLockTest {

public static void main(String[] args) {

DeadLockTestDemo dlt1 = new DeadLockTestDemo(true);

DeadLockTestDemo dlt2 = new DeadLockTestDemo(false);

Thread t1 = new Thread(dlt1);

Thread t2 = new Thread(dlt2);

t1.start();

t2.start();

}

}

进程间的通信:

等待/唤醒机制

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

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

3.botifyAll():唤醒线程池中的所有线程

class Resource

{

String name;

int age;

boolean flag = false;

}

class Input implements Runnable

{

Resource r;

Input(Resource r)

{

this.r = r;

}

public void run()

{

int x = 0;

while(true)

{

synchronized(r)

{

if(r.flag)

try {

r.wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

if(x==0)

{

r.name = "脔割";

r.age = 18;

}

else

{

r.name = "弟鸽";

r.age = 17;

}

r.flag = true;

r.notify();

}

x = (x+1)%2;

}

}

}

class Output implements Runnable

{

Resource r = new Resource();

Output(Resource r)

{

this.r = r;

}

public void run()

{

while(true)

synchronized(r)

{

if(!r.flag)

try {

r.wait();

} catch (InterruptedException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

System.out.println(r.name+"--->"+r.age);

r.flag = false;

r.notify();

}

}

}

public class ResourceDemo {

public static void main(String[] args) {

Resource r = new Resource();

Input in = new Input(r);

Output out = new Output(r);

Thread t1 = new Thread(in);

Thread t2 = new Thread(out);

t1.start();

t2.start();

}

}

线程的wait();notify();notifuAll()定义在Oblect类中的原因是:

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

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

在java中5 % 3_Java基础5相关推荐

  1. 第90节:Java中的Linux基础

    第90节:Java中的Linux基础 linux是装载虚拟机上面的: JDK依赖包: yum install glibc.i686MYSQL依赖包: yum -y install libaio.so. ...

  2. java中的面向对象基础

    java中的面向对象基础 1.对象 #一切客观存在的事物都是对象,万物皆对象. #任何对象,一定具有自己的特征和行为. 2.类 (1)类的定义 (2)对象的创建 (3) 类与对象的关系 类:定义了对象 ...

  3. 第87节:Java中的Bootstrap基础与SQL入门

    第87节:Java中的Bootstrap基础与SQL入门 前言复习 什么是JQ? : write less do more 写更少的代码,做更多的事 找出所有兄弟: $("div" ...

  4. 并发王者课-铂金1:探本溯源-为何说Lock接口是Java中锁的基础

    欢迎来到<并发王者课>,本文是该系列文章中的第14篇. 在黄金系列中,我们介绍了并发中一些问题,比如死锁.活锁.线程饥饿等问题.在并发编程中,这些问题无疑都是需要解决的.所以,在铂金系列文 ...

  5. 铂金1:探本溯源-为何说Lock接口是Java中锁的基础

    欢迎来到<并发王者课>,本文是该系列文章中的第14篇. 在黄金系列中,我们介绍了并发中一些问题,比如死锁.活锁.线程饥饿等问题.在并发编程中,这些问题无疑都是需要解决的.所以,在铂金系列文 ...

  6. Java中的线程基础知识

    Java中的线程基础知识 1.线程概念 线程是程序运行的基本执行单元.当操作系统(不包括单线程的操作系统,如微软早期的DOS)在执行一个程序时,会在系统中建立一个进程,而在这个进程中,必须至少建立一个 ...

  7. 在java中蓝色_Java基础

    cmd命令符 dir:显示当前文件夹下的子文件 cd..:后退上一级的文件 cd 子文件:跳到子文件 cd/:直接跳到根目录 盘符: :跳到相关盘 万能的Tab键:补齐 Java环境配置 1.官网下载 ...

  8. 面试必考之Java中String是基础类型?是包装类型?

    我们都知道,Java中String不属于基础数据类型.基础类型只有8中基本数据类型:byte.short.int.long.float.double.char.boolean,而String是最常用到 ...

  9. Java中的线程基础篇-线程基本概念

    线程的概念.创建方式.生命周期.优缺点 一.基础知识 1. 进程.线程.协程 1.1 进程 1.2 线程 1.3 协程 2. 串行.并发.并行 2.1 串行 2.2 并发 2.3 并行 二.线程的创建 ...

最新文章

  1. 使用docker搭建一个elasticsearch(5.4)的基础环境
  2. 编程珠玑第12章习题
  3. SharePoint 2013 APP 开发示例 (三)使用远程的web资源
  4. Sitecore7.5 安装指南 -- 从.EXE文件安装Sitecore CMS
  5. vscode卸载background插件_使用插件一键启用 Visual Studio Code 的毛玻璃效果
  6. mysql导入100000000需要多久_MYSQL批量插入千万级数据只需百秒
  7. 薅羊毛!1024程序员的狂欢!
  8. 发送附件时,防止文件名中的中文字符变成乱码
  9. LeetCode 1991. 找到数组的中间位置(前缀和)
  10. 利用代码分别实现jdk动态代理和cglib动态代理_代理模式实现方式及优缺点对比...
  11. 解决“The executable was signed with invalid entitlements.”问题
  12. Apache PLC4X开发者向企业下最后通牒:如不提供资助将停止支持
  13. 怎么使用starwind部署iscsi_服务器配置我该怎么选
  14. 微软ReportViewer(rdlc)发布时所需要的动态库(vs2010)
  15. Python生成Wifi二维码 一键联网
  16. Springboot-JAVA实现组织树形结构
  17. 爬虫实战——爬取电影天堂的电影详情页信息
  18. linux系统的超级管理员,系统的超级管理员:root《 Linux 文件与目录权限 》
  19. ACM-ICPC国际大学生程序设计竞赛北京赛区(2015)网络赛 Scores
  20. 关于U盘中的文件全部变成快捷方式的解决办法

热门文章

  1. java is-a_java中 is - a和 has - a的区别
  2. XHTML 语法规则及 HTML/XHTML 文档类型说明(XHTML 1.0/XHTML 1.1 和 HTML 4.01/HTML 5)
  3. java中paint方法和paintComponent方法的不同
  4. windows上搭建NFS服务器
  5. python控制台输入字符串作为参数_Python-如何将字符串传递到subprocess.Popen(使用stdin参数)?...
  6. linux 命令 空格转义,在Linux中,如何转义SCP复制路径中的空格?
  7. Nvidia CUDA初级教程2 并行程序设计概述
  8. python帮助文档中查看内置函数_PYTHON官方文档内置函数整理
  9. Mysql截取中英数混合的字符串
  10. mip-link 组件功能升级说明