当前位置: 首页 > article >正文

7.Java高级编程 多线程

Java高级编程 多线程

文章目录

  • Java高级编程 多线程
  • 一、进程与线程
      • 查看线程
  • 二、线程创建方式
  • 三、线程状态
  • 四、线程常用方法
  • 五、线程安全

一、进程与线程

一个程序有一个进程

一个进程包含多个线程(必须有一个主线程)

并发:

在同一时刻,有多个指令在单个CPU上交替执行

并行:

在同一时刻,有多个指令在多个CPU上同时执行

查看线程

Thread t = Thread.currentThread();//获得当前线程

二、线程创建方式

1.继承Thread类,重写run方法,调用start方法

2.实现Runnable接口,重写run方法,创建Thread对象new Thread(Runnable),调用start

3.实现Callable<数据类型>,重写call方法 **注意:**Callable有返回值

package com.hz.ch01;

public class MyThread extends Thread{
	
	public void run() {
		//书写线程要执行的代码
		for(int i = 0; i<100; i++) {
			System.out.println(getName()+"whfoawh");
		}
	}
}



package com.hz.ch01;

public class Text {

	public static void main(String[] args) {
	/*
	 * 多线程的第一种启动方式:
	 * 		1.自己定义一个类继承Thread
	 * 		2.重写run方法
	 * 		3.创建子类的对象,并启动线程
	 */
		MyThread t1 = new MyThread();
		MyThread t2 = new MyThread();
		//开启线程
		t1.setName("线程1");
		t2.setName("线程2");
		t1.start();
		t2.start();
	}

}



package com.hz.ch02;

public class MyRun implements Runnable{

	@Override
	public void run() {
		//书写线程要执行的代码
		for(int i = 0;i < 100;i++) {
			//获取当前线程对象
			Thread t = Thread.currentThread();
			System.out.println(t.getName()+"HelloWorld");
		}
		
	}

}










package com.hz.ch02;

public class Text01 {

	public static void main(String[] args) {
		/*
		 * 多线程的第二种启动方式:
		 * 		1.自己定义一个类实现Runnable接口
		 * 		2.重写里面的run方法
		 * 		3.创建自己的类的对象
		 * 		4.创建一个Thread类的对象,并开启线程
		 * 
		 */
		
		
			
		//创建MyRun的对象
		//表示多线程要执行的任务
		MyRun mr = new MyRun();
		
		
		//创建线程对象
		Thread t1 = new Thread(mr);
		Thread t2 = new Thread(mr);
		
		//给线程设置名字
		t1.setName("线程1");
		t2.setName("线程2");
		
		//开启线程
		t1.start();
		t2.start();
	}

}

package com.hz.ch03;

import java.util.concurrent.Callable;

public class MyCallable implements Callable<Integer>{

	@Override
	public Integer call() throws Exception {
		//求1-100之间的和
		int sum = 0;
		for(int i = 1;i<=100;i++) {
			sum = sum+i;
		}
		return sum;
	}
}
    
    
package com.hz.ch03;

import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class Text01 {

	public static void main(String[] args) throws InterruptedException, ExecutionException {
		/*
		 * 多线程的第三种运行结果
		 * 特点:可以获取到多线程运行的结果
		 * 
		 * 1,创建一个类MyCallable实现Callable接口
		 * 2.重写call(是有返回值的,表示多线程运行的结果)
		 * 3.创建MyCallable的对象(表示多线程要执行的任物)
		 * 4.创建FutureTask的对象(作用管理多线程运行的结果)
		 * 5.创建Three类的对象,并启动(表示线程)
		 * 
		 * 
		 */
		//创建MyCallable的对象(表示多线程要执行的任物)
		MyCallable mc = new MyCallable();
		//创建FutureTask的对象(作用管理多线程运行的结果)
		FutureTask<Integer> ft = new FutureTask<>(mc);
		//创建线程的对象
		Thread t1 = new Thread(ft);
		//启动线程
		t1.start();
		//获取多线程运行的结果
		Integer resule = ft.get();
		System.out.println(resule);
	}

}
    
    

三、线程状态

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

创建状态:new Thread

就绪状态:调用start()方法

运行状态:执行run()方法

阻塞状态:调用sleep,join会进入阻塞状态,恢复后改为就绪状态->运行

死亡状态:run()运行结束

四、线程常用方法

说 明
void setPriority(int newPriority)更改线程的优先级
static void sleep(long millis)在指定的毫秒数内让当前正在执行的线程休眠
void join()等待该线程终止
static void yield()暂停当前正在执行的线程对象,并执行其他线程
void interrupt()中断线程
boolean isAlive()测试线程是否处于活动状态

wait() 暂停一个线程

notilfy 唤起一个线程

注意:join写在哪个线程阻塞谁,谁调用谁强制执行

sleep使用毫秒 1000毫秒=1秒

使用synchronized修饰的方法控制对类成员变量的访问

访问修饰符 synchronized 返回类型 方法名(参数列表){……}

synchronized 访问修饰符 返回类型 方法名(参数列表){……}

synchronized就是为当前的线程声明一把锁

/**
 * 多人抢票线程
 * @author 26255
 *
 */
public class Writ1 implements Runnable{
	public Integer votes = 10;
	public Integer num = 0;
	@Override
	public void run() {
		
		while(true) {
			
			synchronized (this) {
					if(votes<=0) {
							break;
					}
					votes--;
					num++;
					System.out.println(Thread.currentThread().getName()+"抢到了第几"+num+"张票,剩余"+votes+"张票");
				}
            
            //模拟网络延时
			try {
			Thread.sleep(500);
		} catch (Exception e) {
			e.printStackTrace();
		}
			}
			
		
		
	}

}

-------------------------------------------------------------------------------

public static void main(String[] args) {
		Writ1 writ = new Writ1();
		
		Thread b1 = new Thread(writ,"票口一");
		Thread b2 = new Thread(writ,"票口二");
		Thread b3 = new Thread(writ,"票口三");
		b1.start();
		b2.start();
		b3.start();
	}

五、线程安全

线程安全的类型

** **方法是否同步效率比较适合场景
线程安全多线程并发共享资源
非线程安全单线程

为达到安全性和效率的平衡,可以根据实际场景来选择合适的类型

线程安全的类型

查看ArrayList类的add()方法定义

ArrayList类的add()方法为非同步方法

当多个线程向同一个ArrayList对象添加数据时,可能出现数据不一致问题

ArrayList为非线程安全的类型

Hashtable &&HashMap

​ Hashtable

​ 继承关系

​ 实现了Map接口,Hashtable继承Dictionary类

​ 线程安全,效率较低

键和值都不允许为null

​ HashMap

​ 继承关系实现了Map接口,继承AbstractMap类

​ 非线程安全,效率较高

​ 键和值都允许为null

StringBuffer && StringBuilder

前者线程安全,后者非线程安全
当多个线程向同一个ArrayList对象添加数据时,可能出现数据不一致问题

ArrayList为非线程安全的类型

Hashtable &&HashMap

​ Hashtable

​ 继承关系

​ 实现了Map接口,Hashtable继承Dictionary类

​ 线程安全,效率较低

键和值都不允许为null

​ HashMap

​ 继承关系实现了Map接口,继承AbstractMap类

​ 非线程安全,效率较高

​ 键和值都允许为null

StringBuffer && StringBuilder

前者线程安全,后者非线程安全


http://www.kler.cn/a/311569.html

相关文章:

  • VCS:三步法的仿真流程
  • GNU/Linux - /proc/sys/vm/overcommit_memory
  • 如何解决FPS低的问题?代码优化方法有哪些?
  • 科技大厂裁员潮:行业变革下的阵痛
  • Android setContentView执行流程(1)-生成DecorView
  • 极品模板内容付费管理系统(PHP内容知识付费系统)
  • flutter Dio发送post请求
  • Linux: debug:内核log有乱码^@^@
  • Redis——分布式锁
  • JVM 虚拟机的编译器、类加载过程、类加载器有哪些?
  • Paragon NTFS for Mac和Tuxera NTFS for Mac,那么两种工具有什么区别呢?
  • python中的排序函数sorted
  • 波分技术基础 -- MS-OTN介绍
  • AIGC论文查重是什么?
  • 【Verilog学习日常】—牛客网刷题—Verilog快速入门—VL23
  • C++笔记21•C++11的新特性•
  • Springboot请求响应案例
  • Ruoyi Cloud K8s 部署
  • Golang | Leetcode Golang题解之第415题字符串相加
  • MySQL:索引02——使用索引
  • kafka 超详细的消息订阅与消息消费几种方式
  • 【运维】自定义exporter
  • Redis——笔记01
  • 【PyQt5】object属性
  • Java中的异步编程模式:CompletableFuture与Reactive Programming的实战
  • 性格类型识别系统源码分享