Java多线程
2020-12-13 02:20
标签:监视 catch thread system 不能 调用 编程 内容 列表 什么是程序:有序严谨的指令集称为程序。 什么是进程:程序的同时多运行称为进程。 什么是线程:程序中不同的执行路经称为线程,线程是程序的最小执行单位。 多线程:如果在一个进程中同时运行了多个线程,用来完成不同的工作,则称为”多线程” 新建状态: 就绪状态: 运行状态: 阻塞状态: 等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。 同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。 其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。 死亡状态: 线程优先级由1~10表示,1最低,默认优先级为5 让线程暂时睡眠指定时长,线程进入阻塞状态 Join(long millis); 暂停当前线程,允许其他具有相同优先级的线程获运行机会 线程不同步会遇到的问题:(当多个线程共享同一资源时,一个线程未完成全部操作的时候,其他线程会修改数据,造成数据不安全问题。 Synchronized()内为需同步的对象,通常为this 尽量保证任务数不要超过最大线程数+阻塞队列的长度 Java.util.concurrent Java多线程 标签:监视 catch thread system 不能 调用 编程 内容 列表 原文地址:https://www.cnblogs.com/big-data-sky/p/11031659.html
使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。
当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。
如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:
一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。在Java中创建线程的几种方式
继承Thread类创建线程
//继承Thread类创建线程
public class MyThread extends Thread{
public void run(){
for(int i=0;i){
System.out.println(Thread.currentThread().getName());
}
}
}
public static void main(String[] args) {
MyThread mt = new MyThread();
//需使用start()方法启动线程,如果直接调用线程中run()方法会:
//1.只有主线程一条执行路径2.依次调用了两次run()方法
mt.start();}
实现Runnable接口创建线程
//实现Runnable接口创建线程
public class MyRunnable implements Runnable {
@Override
public void run() {
for(int i=0;i){
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String[] args) {
//创建线程对象
MyRunnable mr = new MyRunnable();
Thread t = new Thread(mr);
t.start();
}
实现Callable接口创建Thread线程
public class MyThread implements Callable
通过Future 创建线程
public class CallableThreadTest implements Callable
线程调度方法:
优先级高的线程获得CPU资源的概率较大
睡眠时间过后线程会再进入运行状态
millis为休眠时长,已毫秒为单位
调用sleep()方法需处理InterruptedException异常
Join(long millis,int nanos);
使当前线程暂停执行,等待其他线程结束后在继续执行本线程
Millis:已毫秒为单位 的等待时长
Nanos:要等待的附加纳秒时长
需处理InterruptedException异常
该线程处于就绪状态,不转为阻塞状态
只是提供一种可能,但是不能保证一定会实现礼让
线程的同步:
线程同步)
synchronized 访问修饰符 返回类型 方法名(参数列表){……}
效果与同步方法相同
synchronized就是为当前的线程声明一把锁
多个并发线程访问同一资源的同步代码块时
同一时刻只能有一个线程进入synchronized(this)同步代码块
当一个线程访问一个synchronized(this)同步代码块时,其他synchronized(this)同步代码块同样被锁定
当一个线程访问一个synchronized(this)同步代码块时,其他线程可以访问该资源的非synchronized(this)同步代码package demo01;
//子线程在调用son方法的时候一上来就能获取同步监视器this
//父线程在调用father函数的时候一上来就是获取不到
//字父线程执行的四种情况: 子 父 父 子 子子 父父
//wait:Object (导致线程阻塞,并释放对同步监视器的占用 )
//notify:Object (唤醒线程的作用,提示后续等待该锁的线程,可以进行访问)
public class FatherAndSon {
boolean flag=true;
public void son(){
synchronized (this) {
//子一定是先执行的
if(!flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i ) {
System.out.println("儿子线程执行第"+(i+1)+"次");
}
flag=false;//1:把机会让给父线程 2、防止子线程再次执行
this.notify();
}
}
public void father(){
synchronized (this) {
//父是后执行的
if(flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i ) {
System.out.println("老子线程执行第"+(i+1)+"次");
}
flag=true;//1:把机会让给子线程 2、防止父线程再次执行
this.notify();
}
}
}
package demo01;
//在Java中什么是所谓的同一资源 static
//只存在一个对象的情况下 ticket
//多个对象: a.ticket b.ticket c.ticket
//保证一种情况:
//synchronized:方法(整个所修饰的方法体都是线程同步的范围)(this:)====>synchronized(this)
//synchronized:代码块(代码块中的内容是线程同步的范围)
public class Test {
public static void main(String[] args) throws InterruptedException {
final FatherAndSon fs=new FatherAndSon();
Thread t1=new Thread(new Runnable(){
@Override
public void run() { //子线程的线程体中
for (int i = 0; i ) {
fs.son();
}
}
});
t1.start();
//父线程的线程体中
for (int i = 0; i ) {
fs.father();
}
}
}
线程池:
顶级接口Executor,真正的线程池接口时ExecutorService
Java.util.concurrent.Executors类提供创建线程池的方法自定义线程池:
/**
*
* 创建自定义线程池
*
* */
public class Test {
public static void main(String[] args) {
//创建自定义线程池 尽量保证:任务数不要超过最大线程数+阻塞队列的长度
ThreadPoolExecutor executor = new ThreadPoolExecutor(5,7,300,TimeUnit.MINUTES,new ArrayBlockingQueue
后台线程的特点: