Java核心类库篇7——多线程

Java核心类库篇7——多线程

1、程序、进程和线程

  • 程序 - 数据结构 + 算法,主要指存放在硬盘上的可执行文件
  • 进程 - 主要指运行在内存中的可执行文件
  • 线程就是进程内部的程序流

操作系统内部支持多 进程的,而每个进程的内部又是支持多线程的

2、线程的创建

方法声明功能介绍
public Thread()使用无参的方式构造对象
public Thread(String name)根据参数指定的名称来构造对象
public Thread(Runnable target)根据参数指定的引用来构造对象,其中Runnable是个接口类型
public Thread(Runnable target, String name)根据参数指定引用和名称来构造对象
public void run()若使用Runnable引用构造了线程对象,调用该方法时最终调 用接口中的版本 若没有使用Runnable引用构造线程对象,调用该方法时则啥也不做
public void start()用于启动线程,Java虚拟机会自动调用该线程的run方法
public long getId()获取调用对象所表示线程的编号
public String getName()获取调用对象所表示线程的名称
public void setName(String name)设置/修改线程的名称为参数指定的数值
public static Thread currentThread()获取当前正在执行线程的引用

2.1、继承Thread类

  • 优点:实现起来简单,而且要获取当前线程,无需调用Thread.currentThread()方法,直接使用this即可获取当前线程
  • 缺点:线程类已经继承Thread类了,就不能再继承其他类,多个线程不能共享同一份资源
public class MyThread extends Thread {@Overridepublic void run() {for (int i = 0; i < 50; i++) {System.out.println(this.getName()+"----------------"+i);}}
}
public class Test {public static void main(String[] args) {new MyThread().start();for (int i = 0; i < 50; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}}
}

注:直接调用run方法如同调用类成员方法一样

2.2、实现Runnable接口

  • 优点:线程类只是实现了接口,还可以继承其他类,多个线程可以使用同一个target对象,适合多个线程处理同一份资源的情况
  • 缺点:通过这种方式实现多线程,相较于第一类方式,编程较复杂,要访问当前线程,必须调用Thread.currentThread()方法
public class MyRunable implements Runnable {@Overridepublic void run() {for (int i = 0; i < 50; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}}
}
public class Test {public static void main(String[] args) {new Thread(new MyRunable()).start();for (int i = 0; i < 50; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}}
}

2.3、Callable和FutureTask

  • 优点:线程类只是实现了接口,还可以继承其他类,多个线程可以使用同一个target对象,适合多个线程处理同一份资源的情况
  • 缺点:通过这种方式实现多线程,相较于第一类方式,编程较复杂,要访问当前线程,必须调用Thread.currentThread()方法
public class Test {public static void main(String[] args) throws ExecutionException, InterruptedException {FutureTask<Integer> futureTask=new FutureTask<Integer>(new Callable<Integer>() {@Overridepublic Integer call() throws Exception {for (int i = 0; i < 50; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}return 100;}});new Thread(futureTask, "ruoye").start();for (int i = 0; i < 50; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}System.out.println(futureTask.get());}
}

lambda表达式

public class Test {public static void main(String[] args) throws ExecutionException, InterruptedException {FutureTask<Integer> futureTask = new FutureTask<>((Callable<Integer>) () -> {System.out.println("hello world!");return 100;});new Thread(futureTask, "ruoye").start();for (int i = 0; i < 50; i++) {System.out.println(Thread.currentThread().getName()+"----------------"+i);}System.out.println(futureTask.get());}
}

3、线程优先级及线程让步

方法声明功能介绍
public static void yield()当前线程让出处理器(离开Running状态),使当前线程进入Runnable 状态等待
public static void sleep(times)使当前线程从 Running 放弃处理器进入Block状态, 休眠times毫秒
public int getPriority()获取线程的优先级
public void setPriority(int newPriority)修改线程的优先级,优先级越高的线程不一定先执行,但该线程获取到时间片的机会会更多 一些
public void join()等待该线程终止
public void join(long millis)等待参数指定的毫秒数
public boolean isDaemon()用于判断是否为守护线程
public void setDaemon(boolean on)用于设置线程为守护线程

sleep

public class Test {public static void main(String[] args) {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");while (true){System.out.println(simpleDateFormat.format(new Date()));try {Thread.sleep(2000);} catch (InterruptedException e) {e.printStackTrace();}}}
}

setPriority线程优先级

public class Test {public static void main(String[] args) {Thread thread = new Thread(() -> {System.out.println(Thread.currentThread().getName()+"优先级-----"+Thread.currentThread().getPriority());for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+"-----"+i);}});thread.setName("ruoye");thread.setPriority(Thread.MAX_PRIORITY);thread.start();for (int i = 0; i < 100; i++) {System.out.println(Thread.currentThread().getName()+"-----"+i);}}
}

线程等待

public class Test {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 10; i++) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"-----"+i);}});thread.setName("ruoye");thread.start();
//        thread.join();
//        System.out.println("终于等到你");thread.join(5000);System.out.println("没有等到你");}
}

守护线程

public class Test {public static void main(String[] args) throws InterruptedException {Thread thread = new Thread(() -> {for (int i = 0; i < 10; i++) {try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}System.out.println(Thread.currentThread().getName()+"-----"+i);}});thread.setName("ruoye");thread.setDaemon(true);thread.start();Thread.sleep(5000);System.out.println("没有等到你");}
}

4、线程同步

4.1、多线程出现的问题

public class Account implements Runnable {private int money;public Account(int money) {this.money = money;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}@Overridepublic void run() {System.out.println("进到门口");System.out.println("开始取钞");if (this.money>200){try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}this.money-=200;System.out.println("取款成功");}}@Overridepublic String toString() {return "Account{" +"money=" + money +'}';}
}
public class Test {public static void main(String[] args) throws InterruptedException {Account account = new Account(1000);Thread thread = new Thread(account);Thread thread1 = new Thread(account);thread.start();thread1.start();thread.join();thread1.join();System.out.println(account.getMoney());}
}

4.2、synchronized同步锁

4.2.1、synchronized代码块

下面所示为锁class,锁Account对象里的成员变量(对象)也可,但请时刻记住,多个Account为对象里的成员变量(对象)多个对象,那么就拥有了多把锁,此时应当用static修饰

休眠在同步代码块内不会让出cpu

public class Account implements Runnable {private int money;public Account(int money) {this.money = money;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}@Overridepublic void run() {System.out.println("进到门口");synchronized (Account.class){System.out.println("开始取钞");if (this.money>200){try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}this.money-=200;System.out.println("取款成功");}}}@Overridepublic String toString() {return "Account{" +"money=" + money +'}';}
}
public class Test {public static void main(String[] args) throws InterruptedException {Account account = new Account(1000);Thread thread = new Thread(account);Thread thread1 = new Thread(account);thread.start();thread1.start();thread.join();thread1.join();System.out.println(account.getMoney());}
}

4.2.2、synchronized方法

当synchronized位于成员方法上等价于synchronized (this)

当当synchronized位于成员方法上等价于synchronized (类对象)

public class Account implements Runnable {private int money;public Account(int money) {this.money = money;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}@Overridepublic synchronized void run() {System.out.println("进到门口");System.out.println("开始取钞");if (this.money>200){try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}this.money-=200;System.out.println("取款成功");}}@Overridepublic String toString() {return "Account{" +"money=" + money +'}';}
}
public class Test {public static void main(String[] args) throws InterruptedException {Account account = new Account(1000);Thread thread = new Thread(account);Thread thread1 = new Thread(account);thread.start();thread1.start();thread.join();thread1.join();System.out.println(account.getMoney());}
}

4.3、死锁问题

尽量减少同步的资源,减少同步代码块的嵌套结构的使用

线程一执行的代码

public void run(){synchronized(a){ //持有对象锁a,等待对象锁b synchronized(b){ //编写锁定的代码; }}
}

线程二执行的代码

public void run(){synchronized(b){ //持有对象锁a,等待对象锁b synchronized(a){ //编写锁定的代码; }}
}

4.4、Lock锁

  • Lock是显式锁,需要手动实现开启和关闭操作,而synchronized是隐式锁,执行锁定代码后自动释放
  • Lock只有同步代码块方式的锁,而synchronized有同步代码块方式和同步方法两种锁
  • 使用Lock锁方式时,Java虚拟机将花费较少的时间来调度线程,因此性能更好
public class Account implements Runnable {private int money;private static Lock lock=new ReentrantLock();public Account(int money) {this.money = money;}public int getMoney() {return money;}public void setMoney(int money) {this.money = money;}@Overridepublic void run() {lock.lock();System.out.println("进到门口");System.out.println("开始取钞");if (this.money>200){try {Thread.sleep(3000);} catch (InterruptedException e) {e.printStackTrace();}this.money-=200;System.out.println("取款成功");}lock.unlock();}@Overridepublic String toString() {return "Account{" +"money=" + money +'}';}
}
public class Test {public static void main(String[] args) throws InterruptedException {Account account = new Account(1000);Thread thread = new Thread(account);Thread thread1 = new Thread(account);thread.start();thread1.start();thread.join();thread1.join();System.out.println(account.getMoney());}
}

5、线程通信

5.1、线程通信

不能锁class

public class Account implements Runnable {private int a;public Account(int a) {this.a = a;}@Overridepublic void run() {while (true){synchronized (this) {if (a<100){System.out.println(Thread.currentThread().getName()+"========"+a);a++;notify();try {wait();} catch (InterruptedException e) {e.printStackTrace();}}else{break;}}}}
}
public class Test {public static void main(String[] args) throws InterruptedException {Account account = new Account(1);Thread ruoye = new Thread(account, "ruoye");Thread yoya = new Thread(account, "yoya");ruoye.start();yoya.start();}
}

5.2、生产者消费者问题

  • 线程间的通信共享数据一定要有同步代码块synchronized
  • 一定要有wait和notify,而且二者一定是成对出现
  • 生产者和消费者的线程实现一定是在while(true)里面
public class Mother implements Runnable {private Account account;public Mother(Account account) {this.account = account;}@Overridepublic void run() {while (true){try {account.produce();Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
public class Ming implements Runnable {private Account account;public Ming(Account account) {this.account = account;}@Overridepublic void run() {while (true){try {account.consumer();Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}}}
}
public class Account {private int a;public Account(int a) {this.a = a;}public int getA() {return a;}public void setA(int a) {this.a = a;}public synchronized void produce() throws InterruptedException {notify();if (a<2000){a+=100;System.out.println("妈妈给小明存了100元");}else{wait();}}public synchronized void consumer() throws InterruptedException {notify();if (a>75){a-=75;System.out.println("小明花了75元");}else{wait();}}
}
public class Test {public static void main(String[] args) throws InterruptedException {Account account = new Account(0);new Thread(new Mother(account)).start();new Thread(new Ming(account)).start();}
}

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

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

相关文章

Java核心类库篇8——网络编程

Java核心类库篇8——网络编程 1、七层网络模型 OSI&#xff08;Open System Interconnect&#xff09;&#xff0c;即开放式系统互联&#xff0c;是ISO&#xff08;国际标准化组织&#xff09;组织在1985 年研究的网络互连模型。 当发送数据时&#xff0c;需要对发送的内容按…

linux网站如何添加swf支持,linux下安装swftools和openOffice

1.openOffice下载地址&#xff1a;http://download.openoffice.org/all_rc.html#untested-full 下载 Linux 32-bit Intel rpm 包 版本自选 2.安装openOffice 1】 tar -zxvf OOo_3.2.1_Linux_x86_install-rpm-wJRE_zh-CN.tar.gz 2】 cd OOO320_m18_native_packed-1_zh-CN1.openO…

Java番外篇1——正则表达式

Java番外篇1——正则表达式 1、什么是正则表达式 正则表达式定义了字符串的模式正则表达式可以用来搜索、编辑或处理文本正则表达式并不仅限于某一种语言&#xff0c;但是在每种语言中有细微的差别 2、正则表达式规则 2.1、普通字符 普通字符包括没有显式指定为元字符的所…

linux 1号硬盘不能用,linux 挂载硬盘的疑问 : IDE1 上的接口无法使用.

状况说明:我将在linux系统上挂载多块硬盘(目前是redhat9).我通过3块硬盘试验.问题出现:无论如何链接 IDE1 上的硬盘, /dev/hdc 都无法 mount.数据:1. 使用 fdisk -l : 不会显示接到 IDE1 上的硬盘(目前只试验了在 IDE1 上接 1个硬盘,用 master 端口).2. 使用 fdisk /dev/hdc : …

Java番外篇2——jdk8新特性

Java番外篇2——jdk8新特性 1、Lambda 1.1、无参无返回值 public class Test {interface Print{void print();}public static void main(String[] args) { // Print printnew Print() { // Override // public void print() { // …

linux同花顺乱码,打开同花顺软件全是问号

官方答案&#xff1a;字体库字体乱码【原因分析】&#xff1a;系统字体缺失&#xff0c;损坏。【解决方案】方案一&#xff1a;使用360电脑门诊进行修复1.打开【360安全卫士】—【电脑专家】搜索乱码&#xff0c;然后会弹出如下六个解决方案&#xff0c;根据当前计算机的故障现…

Java番外篇3——线程池

Java番外篇3——线程池 1、多线程产生的问题 多次创建并销毁线程。而创建并销毁线程的过程势必会消耗内存 2、线程池 降低系统资源消耗&#xff0c;通过重用已存在的线程&#xff0c;降低线程创建和销毁造成的消耗提高系统响应速度&#xff0c;当有任务到达时&#xff0c;通…

嵌入式linux组件,嵌入式Linux系统的几大组件!

原标题&#xff1a;嵌入式Linux系统的几大组件&#xff01;本文概述了Linux系统的几大组件&#xff0c;描述了这些组件之间的关系。文章解释了术语&#xff0c;并描述看似很基础的细节。每个Linux系统都有许多主要组件。其中一个组件(引导加载程序)从技术上讲是Linux之外的&…

linux iptables找不到,centos /etc/sysconfig/下找不到iptables文件解决方法

本想做些防火墙策略。防火墙策略都是写在/etc/sysconfig/iptables文件里面的。可我发现我也没有这个文件。[rootxiaohuai /]# cd /etc/sysconfig/[rootxiaohuai sysconfig]# lsatd firstboot irqbalance network-scripts rhn sysstatauditd grub kdump ntpd rngd sysstat.iocon…

Java番外篇4——BigInteger与BigDecimal

Java番外篇4——BigInteger与BigDecimal 为了解决大数运算的问题 操作整型&#xff1a;BigInteger操作小数&#xff1a;BigDecimal 1、BigInteger 方法声明功能介绍public BigInteger abs()返回大整数的绝对值public BigInteger add(BigInteger val)返回两个大整数的和publ…

linux cd 命令案例,15个关于Linux的‘cd’命令的练习例子

命令名称&#xff1a;cd代表&#xff1a;切换目录使用平台&#xff1a;所有Linux发行版本执行方式&#xff1a;命令行权限&#xff1a;访问自己的目录或者其余指定目录级别&#xff1a;基础/初学者1.从当前目录切换到/usr/local avitecmint:~$ cd /usr/local avitecmint:/usr/l…

c语言字符串strchr,Strchr()C语言字符串处理功能

strchr()函数不如strcpy()&#xff0c;strcat()&#xff0c;strcmp()&#xff0c;strupr()&#xff0c;strlwr()&#xff0c;strlen()直观c strchr函数&#xff0c;因此需要代码理解:代码来自C语言开发入门和项目实战书:#include#includeint main(){字符字符串[50];char * str&…

Java数据库篇1——数据库配置

Java数据库篇1——数据库配置 1、数据库 数据库(DataBase) 就是存储和管理数据的仓库本质是一个文件系统, 还是以文件的方式,将数据保存在电脑上 2、数据库的优点 存储方式优点缺点内存速度快不能够永久保存,数据是临时状态的文件数据是可以永久保存的使用IO流操作文件, 不…

C语言中输入123求位权,数反转 - it610.com

32位系统c语言中&#xff1a;char取值范围:-128~127unsigned char取值范围:0~255int取值范围:-2147483648~2147483647unsigned int取值范围:0~429496729564位系统下C语言中int还是占4字节&#xff0c;32位&#xff0c;与32位系统中没有区别64位系统下&#xff0c;采用64位编译器…

Java数据库篇2——数据库基本操作

Java数据库篇2——数据库基本操作 1、启动、停止、服务 net start mysqlnet stop mysql2、登入登出 本地 Mysql -u用户名 -p密码Mysql -u用户名 -p回车 密码远程 Mysql -hIP地址 -u用户名 -p密码Mysql -hIP地址 -u用户名 -p回车 密码退出 Quit Exit

c语言加密shell脚本,shell脚本加密

如何保护自己编写的shell程序要保护自己编写的shell脚本程序&#xff0c;方法有很多&#xff0c;最简单的方法有两种&#xff1a;1、加密 2、设定过期时间&#xff0c;下面以shc工具为例说明&#xff1a;一、下载安装shc工具shc是一个加密shell脚本的工具.它的作用是把shell脚本…

Java数据库篇3——SQL

Java数据库篇3——SQL 结构化查询语言(Structured Query Language)简称SQL&#xff0c;是一种特殊目的的编程语言&#xff0c;是一种数据库 查询和程序设计语言&#xff0c;用于存取数据以及查询、更新和管理关系数据库系统 1、SQL分类 分类说明数据定义语言简称DDL(Data De…

c语言分配飞机10个座位,leetcode1227(飞机座位分配)--C语言实现

对于第一个乘客来说 他有三种选择坐在正确的(自己的位置), 那么后面的乘客都不会乱&#xff0c;所以第n个乘客可以坐到自己的位置, 1/n * 1.坐在第n个乘客的位置&#xff0c;那么第n个乘客肯定无法坐到自己的位置, 1/n * 0.坐在[1,n-1]之间的某个位置K.对于第K个乘客而言&#…

Java数据库篇4——表的约束

Java数据库篇4——表的约束 1、非空约束 字段不允许为空 #创建表的时候添加 Create table 表名(列1 数据类型 not null&#xff0c;列2 数据类型&#xff0c;列3 数据类型 ); #创建表以后添加 Alter table 表名 modify 列名 数据类型 not null&#xff1b; #删除 Alter tabl…

c语言数组转置原理,为什么这个数组转置不对?

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼原数组是1,2,34,5,67,8,9转置后的数组是1,4,72,5,83,6,9但结果出来的是乱七八糟的数字&#xff0c;而且最后提示出错#includevoid TransposedArray(int Arr[3][3]){shortint i,j;shortint Med;for(i0;i<2;i){for(j0;j<2;j){i…