多线程
public class Class001_Thread extends Thread{
@Override
public void run() {
for(int i = 1;i<=20;i++){
System.out.println("一边喝水");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Class001_Thread th = new Class001_Thread();
th.start();
for(int i = 1;i<=20;i++){
System.out.println("一边讲课....");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
通过实现Runnable接口创建线程
public class Class002_Thread implements Runnable{
public static void main(String[] args) {
Thread th = new Thread(new Class002_Thread());
th.start();
for(int i = 1;i<=20;i++){
System.out.println("一边陪女朋友...");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
@Override
public void run() {
for(int i = 1;i<=20;i++){
System.out.println("一边打游戏...");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
内部类实现线程
public class Class006_Thread {
static class Inner implements Runnable{
@Override
public void run() {
for(int i=1;i<=20;i++){
System.out.println("一边喝水...");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public static void main(String[] args) {
class Inner2 implements Runnable{
@Override
public void run() {
for(int i=1;i<=20;i++){
System.out.println("一边看电影...");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
new Thread(new Inner()).start();
new Thread(new Inner2()).start();
new Thread(new Runnable() {
@Override
public void run() {
for(int i=1;i<=20;i++){
System.out.println("一边看吃零食...");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
new Thread(()->{
for(int i=1;i<=20;i++){
System.out.println("一边看吃吸烟...");
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}
线程状态
线程的状态:
新生状态 : new
就绪状态
运行状态 : cpu调度
阻塞状态
终止状态
一个线程如果一旦进入终止状态,不可恢复
一个线程如果进入到阻塞状态,阻塞解除之后,不能直接恢复到运行,会直接恢复高就绪状态,等待cpu的调度
如何让线程进入到就绪状态:
1.start()
2.阻塞解除
3.cpu的调度切换
4.yield 礼让线程
如何让线程进入阻塞状态:
1.sleep()
2.join() 插队线程
3.wait() 等待
4.IO
如何让线程进入终止状态:
1.正常执行完毕
2.stop() 过时--> 不推荐使用
3.通过标识判断
sleep 线程休眠
static void sleep(long millis) 导致当前正在执行的线程休眠(暂时停止执行)指定的毫秒数,具体取决于系统计时器和调度程序的精度和准确性。
static void sleep(long millis, int nanos) 执行ms+ns
当一个线程调度sleep进入睡眠状态,让出cpu的资源
抱着资源睡觉: 这个资源不是cpu的资源, 值的是对象的锁资源
作用:
放大问题出现的可能性
模拟网络延迟
Thread.State getState() 获取线程状态
Thread.State 线程状态。 线程可以处于以下状态之一:
NEW : new Thread()
尚未启动的线程处于此状态。
RUNNABLE : 就绪|运行
在Java虚拟机中执行的线程处于此状态。
BLOCKED : 等待对象锁的阻塞状态
被阻塞等待监视器锁定的线程处于此状态。
WAITING : wait(),join()等
无限期等待另一个线程执行特定操作的线程处于此状态。
TIMED_WAITING : 与时间相关的等待,sleep(ms),join(ms),wait(ms)...
正在等待另一个线程执行最多指定等待时间的操作的线程处于此状态。
TERMINATED : 终止
已退出的线程处于此状态。
yield 礼让线程
当线程执行到yield方法,会让出cpu的资源,同时线程会恢复就绪状态
join() 插队线程
A线程执行过程中,如果B线程插队了,A线程就会进入到阻塞状态,等待插队线程执行完毕|等待执行的时间,A线程会恢复到就绪状态
void join() 等待这个线程死亡。
void join(long millis) 此线程最多等待 millis毫秒。
void join(long millis, int nanos) 此线程最多等待 millis毫秒加上 nanos纳秒。
void interrupt() 为线程添加一个中断标识
boolean isInterrupted() 测试此线程是否已被中断,是否曾经调用过interrupt方法添加了中断标识
static boolean interrupted() 测试当前线程是否已被中断,是否曾经调用过interrupt方法添加了中断标识,同时复位标识
注意: 当调用sleep方法线程睡眠时 : InterruptedException - 如果有任何线程中断了当前线程。 抛出此异常时,将清除当前线程的中断状态 。
线程优先级与守护线程
线程的优先级 :
方法线程优先执行的可能性
1~10 设置值
1最小 ->static int MIN_PRIORITY 线程可以拥有的最低优先级。
10最大->static int MAX_PRIORITY 线程可以拥有的最大优先级。
5默认值 ->static int NORM_PRIORITY 分配给线程的默认优先级。
int getPriority() 返回此线程的优先级。
void setPriority(int newPriority) 更改此线程的优先级。
线程的分类:
用户线程 : 默认线程为用户线程
守护线程
守护线程 : 守护用户线程的
当所有的用户线程全都执行完毕,守护线程直接结束
垃圾回收机制典型守护线程
void setDaemon(boolean on) 将此线程标记为 daemon线程或用户线程。
同步锁
线程安全
线程安全 :
当多个线程同时操作同一份资源,才有可能出现线程不安全问题
同步锁 synchronized : 有可能出现数据不安全的代码段,让多个线程排队执行
同步的使用:
同步条件 : 协调多个线程排队执行的条件 -->对象的锁
同步的代码 : 需要多个线程排队执行的代码
synchronized用法:
修饰方法 : 同步方法
同步实例方法
条件 : 调用成员方法的对象
代码范围 : 整个方法体
同步静态方法
条件 : 锁类->锁的类的Class对象->一个类只有一个,加载到内存中究存在Class对象,不变,唯一
代码范围 : 整个方法体
修饰块 : 同步块
synchronized(条件){
排队执行的代码;
}
注意:
同步的代码范围太大,效率太低
同步的代码范围太小,锁不住,不安全
同步方法案例(买票)
public class Class002_Web12306 implements Runnable{
int tickets = 100;
@Override
public void run() {
while(true){
if(!buyTicket()){
break;
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized boolean buyTicket(){
if(tickets<=0){
return false;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在购买第"+tickets--);
return true;
}
public static void main(String[] args) {
Class002_Web12306 web = new Class002_Web12306();
Thread th1 = new Thread(web,"张三");
Thread th2 = new Thread(web,"李四");
Thread th3 = new Thread(web,"王五");
th1.start();
th2.start();
th3.start();
}
}
同步块案例(买票)
锁类
public class Class003_Web12306 implements Runnable{
int tickets = 100;
@Override
public void run() {
while(true){
synchronized (Class003_Web12306.class){
if(tickets<=0){
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在购买第"+tickets--);
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Class003_Web12306 web = new Class003_Web12306();
Thread th1 = new Thread(web,"张三");
Thread th2 = new Thread(web,"李四");
Thread th3 = new Thread(web,"王五");
th1.start();
th2.start();
th3.start();
}
}
锁对象
public class Class004_Web12306 implements Runnable{
int tickets = 100;
@Override
public void run() {
while(true){
synchronized (this){
if(tickets<=0){
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在购买第"+tickets--);
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Class004_Web12306 web = new Class004_Web12306();
Thread th1 = new Thread(web,"张三");
Thread th2 = new Thread(web,"李四");
Thread th3 = new Thread(web,"王五");
th1.start();
th2.start();
th3.start();
}
}
锁资源
public class Class005_Web12306 implements Runnable{
Tickets tickets = new Tickets();
@Override
public void run() {
while(true){
synchronized (tickets){
if(tickets.num<=0){
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"正在购买第"+tickets.num--);
}
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static void main(String[] args) {
Class005_Web12306 web = new Class005_Web12306();
Thread th1 = new Thread(new Class005_Web12306(),"张三");
Thread th2 = new Thread(new Class005_Web12306(),"李四");
Thread th3 = new Thread(new Class005_Web12306(),"王五");
th1.start();
th2.start();
th3.start();
}
}
class Tickets{
int num = 100;
}