JavaSE学习之线程初学

1、线程的基本概念

1.线程,又称轻量级进程(Light Weight Process)。是程序中的一个顺序控制流程,同时也是CPU的基本调度单位。由多个线程组成,彼此间完成不同的工作,交替执行,称为多线程。
2.JVM虚拟机是一个进程,当中默认包含主线程(Main),可通过代码创建多个独立线程,与Main并发执行。

2、线程的组成元素

1、CPU时间片:操作系统为每个线程分配的执行时间。
2、运行数据:①堆空间:执行线程的对象,多个线程可以共享堆中的对象。②栈空间:存储线程使用的局部变量,每个线程都拥有独立的栈。
3、线程的逻辑代码。(run()代码)

3、创建线程的四种方式:

1、继承Thread类
2、实现Runnable接口
3、实现Callable接口
4、调用执行器(Executor)创建线程池

代码示例一:

/**
* 单线程示例一
* 1、继承Thread类
* 2、重写run()方法
*/
class Test extends Thread {
	@Overried
	public void run() {
		//线程执行代码
		System.out.println("调用start()方法,自动运行当前对象的run()方法");
	}
}
/**
* 测试类
* 1、创建单线程对象
* 2、调用start()方法,启用线程
*/
public class Test01 {
	public static void main(String[] args) {
		Test t = new Test();
		t.start();
	}
}

代码示例二:

/**
* 单线程示例二
* 1、实现Runnalbe接口
* 2、覆盖run()方法
*/
class Test implements Runnable {
	@Overried
	public void run() {
		//线程执行代码
	}	
}
/**
* 3、创建实现类对象 task01
* 4、创建线程对象 thread01
* 5、线程对象调用thread01.start(task01)方法
*/
public class Test01 {
	public static void main(String[] args) {
		Test t1 = new Test();//创建实现类对象
		Thread t = new Thread(t1);
		t.start();//启动线程
	}
}
4、线程的六种状态

存储在packages:java.lang中
Enums:Thread.State
1、New(初始状态)
2、Runnable(运行状态)
3、Blocked(阻塞状态)
4、Waiting(无限期等待状态)
5、Timed waiting(有限期等待状态)
6、Terminated(终止状态)

状态迁移详解图例一:在这里插入图片描述
状态迁移详解图例二:
在这里插入图片描述
状态迁移详解图例三:
添加锁标记“synchronized”
影响线程运行的方法:

1、休眠 : public static void sleep(long millis)
#当前线程主动放弃时间片,回到就绪状态,竞争下一次时间片
#缺点,占用一个单线程(使当前调用的线程停留)
2、放弃:public static void yiele()
#允许其他线程加入到当前线程中,并优先执行
3、结合:public final void join()

5、线程安全

5.1 导致线程不安全的操作/原因:

情形一、并行与串行会造成线程“数据”的安全问题
需求:A线程将“string1”存入数组的第一个空位;B线程也将“String2”存入数组的第一个空位。
此时会造成线程不安全:
情形二、当线程并发访问临界资源时,如果破坏原子操作,可能会造成数据不一致。
临界资源:共享资源(例如同一个task对象),临界资源一次仅允许一个线程使用时,才能保证它不会重复存入多个数据。
原子操作:不可分割的多步操作,被视为一个整体,其顺序和步骤不可打乱或缺省。

5.2 解决办法:

一、synchronized { //同步代码块 }
1、每个对象都有一个互斥锁标记,用来分配给线程的。
2、只有拥有对象互斥锁标记的线程,才能进入该对象加锁的同步代码块。
3、线程退出同步代码块时,会自动释放相应的互斥锁标记。
二、 synchronized 返回值类型 方法名称(形参列表0) {//代码(原子操作)}
1、只有拥有对象互斥锁标记的线程,才能进入该对象加锁的同步方法中。 2、线程退出同步方法时,会释放相应的互斥锁标记。

三、同步方法示例
JDK中的同步方式实现的线程安全的类有
1.StringBuffer
2.Vector
3.Hashtalbe

6、死锁
概念:多个并发进程因争夺系统资源而产生相互等待的现象,被称为“死锁”。
根本原因:①资源有限;②进程执行顺序发生错误。

6.1 死锁产生的四个必要条件:

1、互斥:资源在多进程间互斥。
2、占有且等待:进程执行需要多种资源,拿到了一部分,同时还等待另一部分,拿到的那部分资源又不会释放。
3、不可抢占:不能抢占已进程占有的资源。
4、循环等待:

6.2 解决办法:
1、线程通信 --------- wait() and notify()
步骤一:在对obj加锁的同步代码块中调用wait()方法,暂停当前线程。此线程会释放其拥有的所有锁标记。同时此线程阻塞处于无限期等待的状态中。释放锁,进入等待队列。
public final void wait() OR public final void wait(long timeout)
步骤二:在对obj加锁的同步代码块中调用notify()方法,从obj的Waiting中释放一个或全部线程。对自身线程没有任何影响。
public final void notify() OR public final void notifyAll()

经典问题2:

生产者–>存储容器–>消费者

5、线程池
线程池的概念:

1.线程容器,可设定线程分配的数量上限。
2.将预先创建的线程对象存入池中,并重用线程池中的线程对象。
3.避免频繁的创建和销毁。

原理:

将任务提交给线程池,由线程池分配线程、运行任务,并在当前任务结束后复用线程。

获取线程池:
1.常用的线程池接口和类(在包java.util.concurrent;中,并发包)
Executor:线程池的顶级接口。
ExecutorService:线程池接口,可调用**submit(Runnable task)**提交任务代码。
Executors:工厂类,通过此类可以初始化一个线程池。

通过newFixedThreadPool(int nThreads) 获取固定数量的线程池。参数:指定线程池中的线程的数量
通过newCachedThreadPool() 获得动态数量的线程池,如不够则参加新的,没有上限。

ExecutorService esf = Executors.newFixedThreadPool(10); //初始化一个固定数量的线程池对象(静态)
ExecutorService esc = Executors.newCachedThreadPool();  //初始化一个线程缓存池(动态)

1.继承Thread类、实现Runnable接口时,线程执行对象.start(),调用了**run()方法,实现线程。
2.Callable<>,传任务给线程去执行,但是它有返回值,调用的是
call()**方法。

public interface Callable {
public V call() throws Exception;
}

JDK5加入,与Runnable接口类似,实现之后代表一个线程任务。
Callable具有泛型返回值,可以声明异常。

Future接口
1.需求:使用两个线程,并发计算150,51100的和,再进行汇总统计。
思考:实际应用中,如何接受call方法的返回值?

概念:异步接受ExecutorService.submit()所返回的状态结果,当中包含了call()的返回值。
方法:V get()以阻塞形式(阻塞主线程)等待Future中的异步处理结果(call()的返回值),拿到值后(确保异步线程执行结束),主线程继续执行,直到结束。

线程池 、 call 、Future

6、线程安全的集合
Lock 接口

重入锁 ReentrantLock
Lock接口的实现类,与synchronized一样,具有互斥功能。
使用步骤:

Lock lo = new ReentrantLock(); //创建重入锁对象
try {
	lo.lock(); //加锁
	// 程序代码
} finally {
	lo.unlock();
}

读写锁ReentrantReadWriteLock
一写多读的同步锁,读写分离,可分别分配读锁、写锁。
支持多次分配读锁,使多个读操作可以并发执行。
互斥规则:
写-写:互斥,阻塞。
读-写:互斥,读阻塞写、写阻塞读。
读-读:不互斥、不阻塞。
在读 操作远远高于写操作的环境中,可在保障线程安全的情况下,提高运行效率。

Lock lo = new RentrantReadWriteLock();
ReadLock rl = lo.Readlock();

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值