文章目录
- Java进程与线程
- 多线程
- java线程的创建
- 构造方法:
- 一些常用方法
- 线程状态
- 线程同步
- 并发与并行
- 什么时候需要线程同步
- 怎么同步
- 线程同步优先使用顺序:
- 死锁
- 线程通信
- 线程池
Java进程与线程
程序 ----> 为了完成某个功能或某个特定任务而用某些特定的语言或代码编写成的一个可以执行的静态代码.
进程 ----> 程序的一次执行 , 或者说进程就是进行中的程序 .
线程 ----> 程序执行的最小单位, 是进程的最小执行单元.
一个进程中可以包含很多个线程, 也就是说一个线程一定是属于某一个进程,线程不能脱离进程而执行,所有线程中有一个线程被称为主线程,
java可以再主线程( mian()) 中创建并启动其他线程. ----->多线程
多线程
1.什么时候需要多线程
–程序需要执行多个任务,或者完成不桶的多个功能时.
–程序需要一些等待任务
–程序需要一些后台执行任务时
2.多线程的好处
–提高程序的相应效率
–提高CPU利用率
–改善程序结构,让不同的任务分开执行
3.多线程不利的方面
可能会使多个线程产生对资源的抢夺现象,竞争资源
java线程的创建
package com.cxy.javathread.day1.Demo1;
public class MyThread extends Thread{
@Override
public void run() {
for(int i = 0;i<10000;i++){
System.out.println("Thread-START:" + i);
}
}
}
通过继承thread类 或者实现Runable接口
–继承thread类
-----重写run()方法即可
—实现runnable接口
----实现run()方法
启动时用 线程.start()启动
package com.cxy.javathread.day1.Demo1;
public class Test {
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
for(int i =0;i<10000;i++){
System.out.println("main:" + i);
}
mt.run();
}
}
构造方法:
Thread() | 创建一个新的线程 |
Thread(String name) | 创建一个指定名称的线程 |
Thread(Runnable target) | 利用Runnable对象创建一个线程,启动时将执行该对象的run方法 |
Thread(Runnable target, String name) | 利用Runnable对象创建一个线程,并指定该线程的名称 |
一些常用方法
方 法 原 型 | 说 明 |
void start() | 启动线程 |
final void setName(String name) | 设置线程的名称 |
final String getName() | 返回线程的名称 |
final void setPriority(int newPriority) | 设置线程的优先级 |
final int getPriority() | 返回线程的优先级 |
final void join()throws InterruptedException | 等待线程终止 |
static Thread currentThread() | 返回对当前正在执行的线程对象的引用 |
static void sleep(long millis)throws InterruptedException | 让当前正在执行的线程休眠(暂停执行),休眠时间由millis(毫秒)指定 |
线程状态
sleep时间片结束或获得了同步锁
|--------阻塞<---------------| sleep()
| | join() wait() 等待同步锁
| 获取cpu执行权 |
新建线程 ----start()--->就绪态<=====================>运行态---执行完run()或异常或stop()---->死亡态
失去cpu执行权或yield
新建:当一个Thread类或其子类的对象被声明并创建时,新生的线程对象处于新建状态
就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU时间片,此时它已具备了运行的条件,只是没分配到CPU资源
运行:当就绪的线程被调度并获得CPU资源时,便进入运行状态,run()方法定义了线程的操作和功能
阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出CPU并临时中止自己的执行,进入阻塞状态
死亡:线程完成了它的全部工作或线程被提前强制性地中止或出现异常导致结束
线程同步
并发与并行
并行---->多个人同时做多件事
并发---->一个人同时做多件事
什么时候需要线程同步
处理并发操作时候
怎么同步
排队 或者加锁
—>synchronized(同步监视器)
这个关键字可以修饰----->方法
public synchronized void spendpoll(){
if(poll>0){
try {
Thread.sleep(500);
}catch (Exception e){
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"-->第 "+(poll)+" 张");
poll--;
}
}
------->代码块
public void run() {
if(flag){
synchronized (a){
System.out.println("true a");
}
}
}
lock()方法
lock时显示锁 — 需要手动的加锁和解锁
synchronized时隐士锁 ----出了作用域自己释放
线程同步优先使用顺序:
Lock >同步代码块(已经进入了方法体,分配了相应资源)>同步方法
死锁
当线程同步时竞争资源而发生的多个线程相互锁死的状态
尽可能避免多个锁互相锁的状态
public void run() {
if(flag){
synchronized (a){
System.out.println("true a");
synchronized (b){
System.out.println(" true a");
}
}
}else {
synchronized (b){
System.out.println("false b");
synchronized (a){
System.out.println(" false a");
}
}
}
}
线程通信
—>生产者消费者问题
生产者(Productor)将产品放在柜台(Counter),而消费者(Customer)从柜台处取走产品,生产者一次只能生产固定数量的产品(比如:1), 这时柜台中不能再放产品,此时生产者应停止生产等待消费者拿走产品,此时生产者唤醒消费者来取走产品,消费者拿走产品后,唤醒生产者,消费者开始等待.
//商品类
package com.cxy.javathread.homework;
public class Apple {
static int num = 1;
static Object obj = new Object();
public static void main(String[] args) {
Person p = new Person();
Shop s = new Shop();
s.start();
p.start();
}
}
//生产者类
package com.cxy.javathread.homework;
public class Shop extends Thread{
@Override
public void run() {
while (true) {
try {
Thread.sleep(20);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (Apple.obj) {
if (Apple.num < 6) {
System.out.println("生产者生产1个--> 总数为:" + Apple.num);
Apple.num++;
}
}
}
}
}
//消费者类
package com.cxy.javathread.homework;
public class Person extends Thread{
int cout ;
@Override
public void run() {
while (true){
try {
Thread.sleep(40);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (Apple.obj){
if(Apple.num>1) {
int now_num = Apple.num-1;
System.out.println("消费者消费1个-->一共买到"+(++cout)+" 还剩-->"+(now_num-1));
Apple.num--;
}
}
}
}
}
线程池
同时创建多个线程 , 需要某个线程就调用,不用放回线程池