二级java程序设计--线程

本文介绍了Java中的线程概念,包括线程的优先级、线程状态与生命周期,以及线程同步的关键概念。通过`synchronized`关键字实现对象锁,避免并发操作中的问题。同时讨论了不应使用的线程控制方法,如`stop()`, `Suspend()`和`resume()`。" 135614612,7337247,PyTorch与Hugging Face在大模型中的应用解析,"['深度学习', '自然语言处理', 'PyTorch', 'Hugging Face', '大模型框架']
摘要由CSDN通过智能技术生成

线程

一.概述

1.多线程是指一个程序中包含多个执行流,多线程是实现并发的一种有效手段
2.java中,线程的模型就是一个CPU,程序代码和数据的封装体

二.线程的创建
1.java中的线程体是由线程类的run()方法声明,在该方法中定义线程的具体行为。线程开始执行时,也是从它的run()方法开始执行。
2.Thread类的构造方法:
public Thread(ThreadGroup group,Runnable target,String name);
(1)group:指明该线程所属的线程组。
(2)target:提供线程体的对象。线程启动时,该对象的run()方法将被调用。
(3)name:线程名称。
3.有两种方法提供run()方法的实现:

(1)实现Runnable接口

import java.lang.*;
public class ThreadTest{
	public static void main(String[] args){
		Thread t1 = new Thread(new Fly());
		Thread t2 = new Thread(new Fly());
		t1.start();
		t2.start();
	}
}

class Fly implements Runnable{
	int i;
	public void run(){
		System.out.println("fly"+i++);
		if(i==10) break;
	}
}
(2)继承Thread类

public class ThreadTest2{
	public static void main(String[] args){
		MyThread mt1 = new MyThread();
		MyThread mt2 = new MyThread();
		mt1.start();
		mt2.start();
	}
}
class MyThread extends Thread{
	int i;
	public void run(){
		System.out.println("fly"+i++);
		if(i==10) break;
	}
}
4.两种方法的比较
(1)采用继承的方法的优点是:程序代码简单,并可以直接调用线程的方法。
(2)实现接口的方法优点是:将不影响Java中Thread类的体系,更加符合面向对象设计的思想;便于继承其他类。

三.线程的调度与控制
1.线程优先级与线程调度策略

java的线程调度策略是一种基于优先级的抢占式调度:java线程的优先级选择高优先级的线程进行运行。

(1)Thread类有三个有关线程优先级的静态常量:MIN_PRIORITY,NORM_PRIORITY,MAX_PRIORITY.
(2)新建线程将继承创建它的父线程的优先级。
(3)一般情况下,主线程具有普通优先级。可以通过getPriority()方法来获得线程的优先级,也可以通过setPriority()方法来设定线程的优先级。

public final int getPriority();
public final void setPriority(int newPriority);

2.线程终止运行的原因可能有多种,如:执行Thread.sleep()调用或等待访问共享的资源。
3.线程的基本控制
Thread类提供了如下基本线程控制方法:
(1)sleep()(使比其优先级低的线程运行):使一个线程暂停运行一段固定的时间
(2)yield()(只让给同优先级运行):调用后,可以使具有与当前线程相同优先级的线程有运行的机会。
(3)join():使当前线程等待,直到结束为止,线程恢复到runnable状态。
(4)interrupt():使线程被阻塞的中断状态被清除。

(5)isAlive():测试线程以确定线程是否还活着。返回true意味着线程已经启动但还没运行结束。

(6)currentThread():静态方法,返回当前线程,具体返回当前线程的引用。


四.线程同步
1.多线程并发操作中的问题
2.对象的锁及其操作
(1)一个程序中单独的,并发的线程对同一个对象进行访问的代码段,称为临界区。java中,临界区可以是一个语句块或者一个方法,并且由"synchronized"标识。
(2)java平台将每个由synchronized语句指定的对象设置一个锁,称为对象锁。
例:使用synchronized进行并发控制

public class MyStack{
	private int idx = 0;
	private char[] data = new char[6];
	public void push(char c){
		synchronized(this){
			data[idx] = c;
			idx++;	//栈顶指针指向栈顶空单元
		}
	}
	public char pop(){
		synchronized(this){
			idx--;
			return data[idx];
		}
	}
}
(3)关于对象锁说明:
<1>返还对象的锁。在如下几种情况下由持有线程返还:
当synchronized()语句块执行完后。
当synchronized()语句块中出现异常。
当持有锁的线程调用该对象的wait()方法。此时该线程将释放对象的锁。
<2>共享数据的所有访问都必须作为临界区,使用synchronized进行加锁控制。
<3>用synchronized保护的共享数据必需是私有的,使线程不能直接访问这些数据,必须通过对象的方法。
<4>如果一个方法的整个方法体都在synchronized中,则可以把该关键字放在方法的声明中。如push()方法可声明为:
public synchronized void push(char c){
data[idx] = c;
idx++;
}
<5>java中对象锁具有可重入性
3.死锁的防治:若程序要访问多个共享数据,则要首先从全局考虑定义一个获得锁的顺序,并且在整个程序中都遵守这个顺序。释放锁时,要按加锁的反序释放。
4.线程间的交互:java引入wait()和notify(),是Object类的方法,实现线程通信的两个方法。
wait()和notify()可以实现线程的同步:
(1)当某线程需要在synchronized块中等待共享数据状态改变时,调用wait()方法,这样该线程等待并暂时释放共享数据对象的锁,其他线程得以获得该对象的锁并进入synchronized块对共享数据进行操作。
(2)当其操作完成后,只要调用notify()方法就可以通知正在等待的线程重新占有锁并运行。

5.不建议使用的方法:stop(),Suspend()和resume()


五.线程状态与生命周期:新建状态,可运行状态,运行状态,阻塞状态,终止状态
1.新建状态(new):调用一个线程类的构造方法,便创建了一个线程
创建线程后并没骂马上启动线程,此时线程处于新建状态,只能使用start()和stop()两种控制方法。
2.可运行状态(Runnable):新建的线程调用start()方法,使线程从新建状态转换为可运行状态。
3.运行状态:线程占有CPU并实际运行的状态,此时线程状态的变迁有三种情况:
(1)若线程正常执行结束或应用程序停止运行时,线程将进入终止状态。
(2)若当前线程执行了yield(),或是当前线程因调度策略从而导致当前线程进入可运行状态。
(3)若发生下几种情况时,线程就进入阻塞状态。
[1]线程调用了sleep()方法,join()方法时,线程进入了阻塞状态。
[2]线程调用wait()方法时,线程由运行状态进入阻塞状态。
[3]若线程中使用synchronized来请求对象锁而未获得时,进入阻塞状态。
[4]若线程中有输入输出操作,也将进入阻塞状态。
4.阻塞状态:根据产生原因:对象锁阻塞,等待阻塞和其他阻塞。
5.终止状态:线程执行结束的状态,没有任何方法可改变它的状态。

六.线程相关的其它类和方法
1.支持线程的类java.lang.Thread,java.lang.Runnable,java.lang.Object
2.线程组:java中的每个线程都属于某个线程组。在创建线程时可以显式指定线程组。
3.Thread类的其他方法:setName(),getName()等。














评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值