多线程
程序在快速切换(时间片)完成多线程的操作
并行:同一时间点执行多个任务,多核操作
并发:同一个时间段执行多个任务,单核快速切换
说说进程和线程的区别
一个进程可以运行多个线程,多个进程的数据很难进行共享,多个进程可以同时运行
一个线程就是进程的一个执行单元,多个线程可以共享数据,多个线程只能在cpu中逐个运行
一个Java程序启动后至少有几个线程?他们的作用是什么?
最少需要两个线程:main主线程,后台线程
主线程作用:运行简单的java程序
后台线程的作用:清理运行java程序过程中所产生的垃圾
自定义线程的方式有几种?他们的区别是什么?
自定义线程的方式有两种:
继承Tread类:Tread父类中有许多写好的功能可以直接使用,创建对象的时候比较方便,启动线程的时候也很方便
示例:
public class GameThread extends Thread {//通过复写run方法来实现当前线程需要执行的任务@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println("玩游戏");}}}public static void main(String[] args) {
//创建线程对象GameThread game = new GameThread();game.start();//开启线程的方法(执行线程的任务)//使用start方法,不是run方法
实现Runable接口:该接口里面只有一个run方法,只能依赖Trea进行启动,但这种方式可以让多个对象共享一个资源,比Tread方法更好
示例:
public class GameRunable extends Thread {//通过复写run方法来实现当前线程需要执行的任务@Overridepublic void run() {for (int i = 0; i < 100; i++) {System.out.println("玩游戏");}}}public static void main(String[] args) {GameRunable gameRunable = new GameRunable();Thread gameThread = new Thread(gameRunable);gameThread.start();}
说说线程的生命周期和不同状态的线程的转换关系
1.新生状态:new线程的时候存在,调用star()方法进入就绪状态
2.可运行状态:就绪状态:此时程序还没有运行,等待cpu的调度
运行状态:执行里面的run方法,直到阻塞或完成任务而死亡
阻塞状态:遇到 特殊情况,同步,等待i/o会暂停执行,进入等待状态
等待状态:一个程序由可运行状态转为等待状态,等到另一个线程执行完成后再转到可运行状态继续执行
计时等待状态:设定一个提示器等待特定时间,等待时间段结束后,无论上一个程序是否执行完毕,该程序都会执行
终止状态:表示线程结束.
说说同步和异步的区别
同步:将多线程执行效果转为单线程执行,串行执行,后面的线程只能等待前面的线程执行完成后子再执行,这样等待的时间太长,比较安全
异步:将线程执行时的等待时间用来执行其他的线程,等该线程的等待时间结束再抢占cpu资源进行执行,比较节约时间,但是不安全
说说你对多线程并发访问带来的问题的理解
当多个线程访问同一个资源的时候,会出现第一个线程还没有执行完还在等待的时候,另一个线程抢占到cpu的资源就进去执行,此时里面的变量会改变,此时第一个线程再执行时的变量已经发生了改变,结果就会出错,就会导致线程出现安全问题.
如何解决多线程并发访问带来的问题?
给线程增加一个同步锁,该锁的作用就是谁先拿到这个锁,谁就先执行,其他的线程只能在外面等待该线程执行完成后才能进去执行,保证线程的安全.
同步代码块
//继承Tread:
public class TiickedWindow extends Thread{private static int number=1;//static用来固定数量//任意创建一个对象,保证多个线程共享该对象,作为对象private static Object o=new Object();public TiickedWindow(String name ){super(name );}public void run(){for (int i = 1; i < 50; i++) {if (number >= 50) {break;}//使用同步锁synchronized (o){System.out.println(Thread.currentThread().getName()+"卖出第" + number + "张票");number++;}}}}//实现Runable接口public class TickedRunable implements Runnable {private int number = 1;@Overridepublic void run() {//获取线程的名字:先获取线程,再获取线程名字for (int i = 1; i < 50; i++) {if (number > 50) {break;}//将同步的代码块放在同步代码块中//同步锁,保证多个线程使用同一把锁(对象)synchronized (this){System.out.println(Thread.currentThread().getName()+"卖出第" + number + "张票");number++; }} }}
同步方法:
//继承Tread
public class TiickedWindow extends Thread{private static int number=1;//static用来固定数量public TiickedWindow(String name ){super(name );}//使用静态方法synchronized public static void sellTicked(){if(number>50){return;}System.out.println(Thread.currentThread().getName()+"卖出第" + number + "张票");number++;}public void run(){for (int i = 1; i < 50; i++) {sellTicked();}}}//实现Runable接口
public class TickedRunable implements Runnable {private int number = 1;synchronized public void sellTicked() {if (number > 50) {return;}System.out.println(Thread.currentThread().getName() + "卖出第" + number + "张票");number++;}@Overridepublic void run() {//获取线程的名字:先获取线程,再获取线程名字for (int i = 1; i < 50; i++) {sellTicked();}}}