标签:监视 catch thread system 不能 调用 编程 内容 列表
什么是程序:有序严谨的指令集称为程序。
什么是进程:程序的同时多运行称为进程。
什么是线程:程序中不同的执行路经称为线程,线程是程序的最小执行单位。
多线程:如果在一个进程中同时运行了多个线程,用来完成不同的工作,则称为”多线程”
新建状态:
使用 new 关键字和 Thread 类或其子类建立一个线程对象后,该线程对象就处于新建状态。它保持这个状态直到程序 start() 这个线程。
就绪状态:
当线程对象调用了start()方法之后,该线程就进入就绪状态。就绪状态的线程处于就绪队列中,要等待JVM里线程调度器的调度。
运行状态:
如果就绪状态的线程获取 CPU 资源,就可以执行 run(),此时线程便处于运行状态。处于运行状态的线程最为复杂,它可以变为阻塞状态、就绪状态和死亡状态。
阻塞状态:
如果一个线程执行了sleep(睡眠)、suspend(挂起)等方法,失去所占用资源之后,该线程就从运行状态进入阻塞状态。在睡眠时间已到或获得设备资源后可以重新进入就绪状态。可以分为三种:
等待阻塞:运行状态中的线程执行 wait() 方法,使线程进入到等待阻塞状态。
同步阻塞:线程在获取 synchronized 同步锁失败(因为同步锁被其他线程占用)。
其他阻塞:通过调用线程的 sleep() 或 join() 发出了 I/O 请求时,线程就会进入到阻塞状态。当sleep() 状态超时,join() 等待线程终止或超时,或者 I/O 处理完毕,线程重新转入就绪状态。
死亡状态:
一个运行状态的线程完成任务或者其他终止条件发生时,该线程就切换到终止状态。
//继承Thread类创建线程 public class MyThread extends Thread{ public void run(){ for(int i=0;i<100;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接口创建线程 public class MyRunnable implements Runnable { @Override public void run() { for(int i=0;i<100;i++){ System.out.println(Thread.currentThread().getName()); } } public static void main(String[] args) { //创建线程对象 MyRunnable mr = new MyRunnable(); Thread t = new Thread(mr); t.start(); }
public class MyThread implements Callable<Integer> { @Override public Integer call() throws Exception { System.out.println("子线程:"+Thread.currentThread().getName()); return null; } } public class Test { public static void main(String[] args) { FutureTask<Integer> ft = new FutureTask<Integer>(new MyThread()); Thread t = new Thread(ft,"01"); System.out.println("主线程:"+Thread.currentThread().getName()); t.start(); } }
public class CallableThreadTest implements Callable<Integer> { public static void main(String[] args) { CallableThreadTest ctt = new CallableThreadTest(); FutureTask<Integer> ft = new FutureTask<>(ctt); for(int i = 0;i < 100;i++) { System.out.println(Thread.currentThread().getName()+" 的循环变量i的值"+i); if(i==20) { new Thread(ft,"有返回值的线程").start(); } } try { System.out.println("子线程的返回值:"+ft.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } @Override public Integer call() throws Exception { int i = 0; for(;i<100;i++) { System.out.println(Thread.currentThread().getName()+" "+i); } return i; } }
线程优先级由1~10表示,1最低,默认优先级为5
优先级高的线程获得CPU资源的概率较大
让线程暂时睡眠指定时长,线程进入阻塞状态
睡眠时间过后线程会再进入运行状态
millis为休眠时长,已毫秒为单位
调用sleep()方法需处理InterruptedException异常
Join(long millis);
Join(long millis,int nanos);
使当前线程暂停执行,等待其他线程结束后在继续执行本线程
Millis:已毫秒为单位 的等待时长
Nanos:要等待的附加纳秒时长
需处理InterruptedException异常
暂停当前线程,允许其他具有相同优先级的线程获运行机会
该线程处于就绪状态,不转为阻塞状态
只是提供一种可能,但是不能保证一定会实现礼让
线程不同步会遇到的问题:(当多个线程共享同一资源时,一个线程未完成全部操作的时候,其他线程会修改数据,造成数据不安全问题。
线程同步)
Synchronized()内为需同步的对象,通常为this
效果与同步方法相同
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 < 3; 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 < 5; 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 < 10; i++) { fs.son(); } } }); t1.start(); //父线程的线程体中 for (int i = 0; i < 10; i++) { fs.father(); } } }
尽量保证任务数不要超过最大线程数+阻塞队列的长度
Java.util.concurrent
顶级接口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<Runnable>(4)); for(int i=0;i<12;i++){ executor.execute(new MyRunnable(i)); System.out.println("线程池中线程数:"+executor.getPoolSize()+",对列中等待任务执行数:"+executor.getQueue().size()+",已经执行完的任务数:"+executor.getCompletedTaskCount()); } executor.shutdown(); } } class MyRunnable implements Runnable{ int num;//第几个任务 public MyRunnable(int num) { super(); this.num = num; } @Override public void run() { System.out.println("正在执行任务"+num); try { Thread.sleep(2000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("任务"+num+"执行完毕"); } }
标签:监视 catch thread system 不能 调用 编程 内容 列表
原文地址:https://www.cnblogs.com/big-data-sky/p/11031659.html