DAY21
并发:
并发,在操作系统中,是指一个时间段中有几个程序都处于已启动运行到运行完毕之间,且这几个程序都是在同一个处理机上运行,但任一个时刻点上只有一个程序在处理机上运行。
并行 :
并行是指在同一个时刻执行,两个或者是多个操作
进程:
一个正在运行程序,在内存里开辟空间
线程:
表示每一条执行的路径
进程与线程之间的关系:
一个进程里可以存在多个线程, 而一个线程只能在一个进程里
线程分配情况 :
- 按照时间均匀的分配 (两个线程交替执行,以时间为标准) (不存在)
- 抢占式分配:任意一个线程, 谁能够抢到cpu的资源谁执行(java)
单纯的执行main 方法:属于单线程,从上到下执行
如何来实现多线程:
1. 继承线程类 类:Thread
Java 虚拟机允许应用程序并发地运行多个执行线程
实现多线程的步骤:
- 创建一个Thread 的子类
- 重写其run( ) (run方法也就是子线程要执行的操作)
- 实例化这个子类
- 调用 start( ) 开启线程
注意点:
- 如果直接调用run() ,是在主线程里执行,没有在cpu新开辟一条执行的路径,只有调用start( ) 这个方法才会去开辟一条新的路径
- 一个线程只能够开启一次,重复开启会产生错误: java.lang.IllegalThreadStateException
2.实现这个接口 Runnable
实现的步骤:
- 定义一个类来实现这个接口
- 实现run( )方法
- 实例化这个实现类
- 实例化一个Thread,传递参数是这个实现类
- 调用start()方法
使用这个方式的好处:
- 解决java单继承的问题
- 可扩展性增强, 实现申明与调用的分离,降低了耦合度
- 继承Thread实际上 还是实现了这个接口
实现多线程
效率:对于整个系统来说,效率是提高,但是对于具体的某一个线程,效率就是降低
使用类名内部来实现多线程:
第一种方式:Thread thread = new Thread(new Runnable( ) { }
第二种方式:Runnable runnable = new Runnable() { }
线程中常规的一些方法:
-
返回对当前正在执行的线程对象的引用(也就是当前线程)
public static Thread currentThread( )
-
获取线程的名称,线程名字的默认规则是 Thread+i(i 是从0开启)
getName( )
-
设置线程的名称 (一定要在开启线程之前进行设置)
public final void setName(String name)
-
通过构造的方式来设置线程的名称:
public Thread(Runnable target,String name)
-
表示让当前线程睡一会,别的线程可以执行了
public static void sleep(long millis)
-
设置线程的优先级 最小是1 默认是5 最大是10
public final void setPriority(int newPriority)
//注意: 设置优先级不一定是最先执行,只是优先执行的机遇更大一点
-
如果有两个线程: A线程 调用了join方法, A线程执行完成之后,B线程才能执行
public final void join() //注意点 :这个方法必须在线程开启之后进行调用
-
礼让 : 如果有A线程 B线程, 这如果A线程调用了yield() 并不一定b线程就会执行
public static void yield( )\
-
守护线程 :如果A,B 线程 A是被守护线程 B是守护线程,如果A终止了,B线程也会终止
public final void setDaemon(boolean on) public final boolean isDaemon( ) //判断其是否是守护线程
电影票问题(解决同步问题)
一、同步代码块:
语法:
synchronized (){ }
- ( ) 里面是对象,这个对象可以是任意的对象
- { } 里面会出现共享数据问题的代码
注意点:
- 对象可以是任意的对象
- 三个对象必须是这个锁对象
- 锁对象,保证只有一个线程进入
二、同步方法:
- 把可能出现数据问题的代码抽取成一个方法
- 给方法加上锁的关键字(synchronized)
三、Lock (不是特别常用)
Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作,此实现允许更灵活的结构。
实现类: ReentrantLock( )
常规的两个方法:
- public void lock( ) 获取锁
- public void unlock( ) 释放锁
使用步骤:
- 实例化这个对象
- 在同步可以出现数据异常的头部调用其lock()
- 在同步可以出现数据异常的 尾部加上 unlock()
三种方法都是为了解决问题:解决多线程中共享数据的问题
总结
今天主要学习了多线程的问题,首先了解了线程的概念,同时也尝试使用多线程的方式解决实际问题,在使用多线程的时候,主要使用实现Runnable这个接口进而再使用同步代码块解决问题
疑问
为什么不能实现多线程均衡分配资源,必须抢占资源,这种不稳定性不会导致程序不稳定吗?