Java Se----多线程
来源:互联网 发布:ssd nvme ubuntu 分区 编辑:程序博客网 时间:2024/04/30 05:44
一、进程:
1. 概念:
I. 程序是静止的概念,而进程是程序的实体,在CPU执行时,才被 赋予生命,只有当程序真正的running时,被称为进程。
II. 在任何时间点、时间戳,只能有一个进程在执行,宏观并行、微观 串行。
二、线程:
1. 概念:
I. 轻量级进程(Light Weight Process LWP),代表进程中一个单一的 顺序控制流程。
II. CPU调用的基本单位是线程(调用某一进程中的某一线程)。
III. 在单个进程中“同时”运行多个线程完成不同的工作,交替执行, 称为多线程。
2. 组成:
I. CPU:操作系统分配时间片(Windows:5~20ms、Linux:5~800ms)。
II. 数据:堆空间共享(对象),栈空间独立(变量)。
III. 代码:
1). 继承Thread类:
a. 覆盖run方法。
b. 创建子类对象: Thread t1 = new MyExtendsThread();
c. 启动线程: t1.start();
package thread;public class TestBaseThread1 {public static void main(String[] args) {Thread t1 = new MyExtendsThread();//t1.run();//Error 手工调用普通方法t1.start();for (int i = 0; i <= 100; i++) {System.out.println("Main: " + i);}}}class MyExtendsThread extends Thread{@Overridepublic void run() {for (int i = 0; i <= 100; i++) {System.out.println("T1 : " + i);}}}
2). 实现Runnable接口:
a. 覆盖run方法。
b. 创建子类对象: Runnable r = new MyImplRunnable();
c. 创建线程对象: Thread t2 = new Thread(r);
d. 启动线程: t2.start();
package thread;public class TestBaseThread2 {public static void main(String[] args) {Thread t1 = new MyExtendsThread2();//t1.run();//Error 手工调用普通方法Runnable r= new MyImplRunnable();//定义了真正的running的时候,所需要执行的内容 TaskThread t2 = new Thread(r);t1.start();//启动线程(当t1获取到时间片之后,有JVM调用该线程的run方法)t2.start();}}class MyExtendsThread2 extends Thread{@Overridepublic void run() {for (int i = 0; i <= 100; i++) {System.out.println("T1 : " + i);}}}class MyImplRunnable implements Runnable{@Overridepublic void run() {for (int i = 0; i <= 100; i++) {System.out.println("---T2:" + i);}}}
3). 常用方法:(造成阻塞)
public static void sleep(long millis) //当前线程休眠
public static void yield() //放弃、让出时间片
public final void join() //将其他线程加入到自身线程中,优先执行
package thread;public class TestThreadMethod {public static void main(String[] args) {Thread t1 = new MyThread1();Thread t2 = new MyThread2();t1.start();//t2.start();for (int i = 0; i <= 100; i++) {System.out.println("Main:" + i);if(i == 20){try {t1.join();//加入(让t1 线程加入到当前线程中,并优先执行t1)} catch (Exception e) {e.printStackTrace();}}}}}class MyThread1 extends Thread{@Overridepublic void run() {for (int i = 0; i <= 100; i++) {System.out.println("T1 :"+ i );/*if(i == 50){//休眠try {Thread.sleep(200);//当前线程休眠} catch (Exception e) {}}*/}}}class MyThread2 extends Thread{@Overridepublic void run() {for (int i = 0; i <= 100; i++) {System.out.println("---T2:"+ i );/*if(i % 10 == 0){Thread.yield();//放弃、让出时间片}*/}}}
三、线程同步【重点】:
1. 线程不安全:当多线程并发访问临界资源时,如果破坏原子操作,可 能造成数据不一致。
I. 临界资源:共享资源(同一对象)。
II. 原子操作:不可分割的多个步骤,被视为一个整体,其顺序不可打 乱或缺省。
2. 互斥锁标记:每个对象都有一个互斥锁标记,用来分配给线程的。
3. 锁池:每个对象都有一个锁池,用来存储等待该对象锁标记的线程的
4. 同步方式【重点】:
1). 同步代码块:
synchronized(临界资源){ //可为临界资源加锁
//原子操作
}
2). 同步方法:
synchronized 返回值类型 方法名称(形参列表){
//原子操作
}
注:在调用同步方法时,需要对象的锁标记,而调用非同步方法时, 不需要锁标记,可直接访问。
package synchronize;public class TestSynchronized {public static void main(String[] args) {Account acc = new Account();Husband hus = new Husband(acc);Wife wife = new Wife(acc);hus.start();wife.start();}}class Account{//账户String cardNo = "622200282789479382793";//卡号String passworld = "123456";//密码Double balance = 2000D;//余额public void take(String no,String pwd , Double money){if(cardNo.equals(no) && passworld.equals(pwd)){System.out.println("登陆成功,请稍后。。。");if(money <= balance){System.out.println("正在处理,请稍后。。。");balance -= money;System.out.println("取款成功,当前余额为"+ balance);}else{System.out.println("卡内余额不足");}}else{System.out.println("账号或密码错误");}}}class Husband extends Thread{//丈夫Account account = null;public Husband(Account account){this.account = account;}@Overridepublic void run() {synchronized (account){//为account对象加锁this.account.take("622200282789479382793", "123456", 1200D);}}}class Wife extends Thread{//妻子Account account = null;public Wife(Account account){this.account = account;}@Overridepublic void run() {synchronized (account){//为account对象加锁this.account.take("622200282789479382793", "123456", 1200D);}}}
四.死锁
一个线程可以同时拥有多个对象的锁标记,当线程阻塞在锁池中时,不会释放已经拥有的锁标记,由此可能造成死锁
线程间的通信:等待——通知
任何对象都有一个等待队列,用来存放线程
T1:o.wait(): 必须放在对o加锁的同步代码块中,T1会释放其拥有的所有标记,同时T1会阻塞在o的等待队列中
T2:o.notify()/notifyAll() :必须放在对o加锁的同步代码块中,从o的等待队列中,释放一个/全部 线程
修饰符组合:
Synchronized 和 static连用:可以连用,给当前类对象加锁
Synchronized 和 abstract连用:不可以
Synchronized 和构造方法连用:不可以
package synchronize;public class TestWaitNotify {public static void main(String[] args) throws Exception {Object o = new Object();Thread t = new SubThread(o);t.start();synchronized(o){System.out.println("Main1");o.wait();System.out.println("Main2");}}}class SubThread extends Thread{Object o;public SubThread(Object o) {this.o = o;}public void run(){synchronized(o){System.out.println("Sub1");o.notifyAll();System.out.println("Sub2");}}}
- Java SE -- 多线程
- java se 多线程下载
- java SE基础(多线程)
- Java Se----多线程
- Java SE -- 多线程 线程终止
- Java SE -- 多线程 线程通信
- Java SE -- 多线程 线程生命周期
- Java SE学习笔记-多线程
- Java SE -- 多线程 线程安全问题解决
- Java SE -- 多线程 生产者消费者模型
- java SE 文件多线程下载,断点续传 原理
- 多线程下载基础示例JAVA SE
- android_33_多线程下载(Java SE版本)
- Java SE(六)—— 多线程
- java se--8.多线程-1.基本概念
- java se--8.多线程-4.生命周期
- java SE多线程(关于runnable接口实现多线程)
- 【Java SE系列总结篇】:Java多线程(一)
- 五类排序算法(插入,交换,选择,归并)
- windows核心编程-第一章 对程序错误的处理
- Java_IO_SequenceInputStream文件的合并
- 考银行必须要有银行从业资格证吗?
- ubuntu 命令行模式和图形界面切换
- Java Se----多线程
- 怎么预防空调病呢?
- TestNG的IMethodInterceptor监听器详解
- Android判断view是否部分被遮挡(或者移出屏幕)的方法
- JavaWEB——文件上传与下载
- zzulioj 1912: 小火山的爱情密码
- OC中的KVC和KVO(二)
- 初识Pyspark 1
- 什么是脚本(Script)