Java线程生命周期、Synchronized同步、互斥锁、死锁、释放锁基本入门

Java学习-09-韩顺平老师

Java-线程入门01

目录:

01-线程的生命周期
02-Synchronized同步
03-互斥锁
04-死锁
05-释放锁

线程的生命周期

线程状态转换图:
在这里插入图片描述

线程的七大状态:

1.NEW:尚未启动的线程处于此状态
2.RUNNABLE:在虚拟机上执行处于此状态。
3.BLOCKED:被堵塞等待监视器锁定的线程处于此状态。
4.WAITING:正在等待另一个线程执行特定动作的线程处于此状态。
5.TIMR_WAITING:正在等待另一个线程执行动作达到指定时间的线程处于此状态。
6.TERMINATED:已退出的线程处于此状态。
7.RUNNABLE状态实际上再JVM底层是被分为Ready(在运行状态,但是在等待运行)和RUNNING(正在运行状态)

Synchronized同步

线程同步机制:

1.在多线程编程,一些敏感的数据不允许被多个线程同时访问,此时就是用
  同步访问技术,保证数据在任何每一时刻,最多可以由一个线程来方法,
  以保证数据的完整性。
2.也可以这样理解:线程同步,即当一个线程在对内存操作的时候,其他线程
  都不可以对这个内存进行操作,直到线程操作完,其他线程才能操作该内存。

两种实现方法:
1.同步代码块

synchronized(对象){ 得到对象的锁,才能操作代同步代码
	需要同步的代码块
}

2.synchronized还可以放在方法声明中,表示这个方法是同步方法。

public synchronized void m(String name) {
	// 需要同步代码块
}

Synchronized解决超出售票问题

public class SellTicket {
    public static void main(String[] args) {
        WindowSell windowSell = new WindowSell();
        // 创建三个线程同时开始操作总共的票数
        new Thread(windowSell).start();
        new Thread(windowSell).start();
        new Thread(windowSell).start();
    }
}
@SuppressWarnings({"all"})
class WindowSell implements Runnable{
    public static int tickets = 100; // 定义静态属性,所有的窗口对象共享
    public static Object obj = new Object();
    @Override
    public void run() {
        while (true){
        	// 互斥锁是本身 采用代码块形式实现同步
        	// 当然也可以在上面定义一个对象,例如上面定义的Object
        	// 则可以写出 synchronized (obj){
        	// 无论换成哪一个对象,对象必须是所有WinddowSell实例化对象所共有的
        	// 才可以实现互斥锁。  
            synchronized (this){  
                if(tickets == 0){
                    System.out.println("没有票了");
                    break;
                }
                tickets--;
                System.out.println("窗口"+ Thread.currentThread() + "售出一张票,剩余" + tickets);
                try {
                    Thread.sleep(50);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

互斥锁

基本介绍:

1.在Java语言中,引入了对象互斥锁的概念,来保证共享数据操作的完整性。
2.每个对象都有对应于一个可称为"互斥锁"的标记,每个标记用来保证任一
  时刻,只能有一个线程访问该对象。
3.关键字synchronized来与对象的互斥锁练习,当某个对象用synchronized
  修饰时,表明该对象在任意时刻是能由一个线程来访问。
4.同步的局限性:导致程序的执行效率降低。
5.同步方法(非静态)的锁可以时this,也可以是其他对象(要求是同一个对象)。
6.同步方法(静态的)的锁为当前类本身。

注意细节:

1.同步方法没有使用static修饰:默认锁对象是this
2.如果用方法使用修饰,默认锁对象:当前类本身.class
3.具体事项步骤:
	1.需求分析上锁的代码。
	2.选择同步代码块或同步方法。
	3.要求多个线程的锁对象是同一个。
演示代码可以参考synchronized演示代码

死锁

基本介绍:

多线程都占用对方的锁资源,但不肯想让,导致死锁,在编程过程中要避免死锁的发生。

演示死锁:

public class Deadlock {

    public static void main(String[] args) {
        new AA(true).start(); // 线程1
        new AA(false).start(); // 线程2
    }
}

class AA extends Thread {
    public static Object obj1 = new Object();
    public static Object obj2 = new Object();
    public boolean flag;

    public AA(boolean flag) {
        this.flag = flag;
    }

    @Override
    public void run() {
        if (this.flag) {
        	// 线程1 进入
            synchronized (obj1) {
            	// 线程1获得了对象obj1 的锁进入1
                System.out.println(Thread.currentThread() + "进入了1");
                // 线程1需要获取obj2的锁,但是这个锁,被线程2进入else语句占用了
                // 所以无法既然进入2
                synchronized (obj2) {
                    System.out.println(Thread.currentThread() + "进入了2");
                }
            }
        } else {
        	// 线程2 进入
            synchronized (obj2) {
            	// 获得对象obj2的锁,进入3
                System.out.println(Thread.currentThread() + "进入了3");
                // 线程2需要获取obj1的锁,但是这个锁,被线程2进入else语句占用了
                // 所以无法既然进入4
                synchronized (obj1) {
                    System.out.println(Thread.currentThread() + "进入了4");
                }
            }
        }
    }
}
// 最终两人人都不能获得对方占用的锁,处于死锁状态,导致程序不会结束

释放锁

以下操作会释放锁:

1.当线程的同步方法、同步代码块执行完毕后,会释放锁。
2.当线程在同步代方法、同步代码块中遇到break或者return时,会释放锁。
3.当线程同步方法、同步代码块中出现未处理的Error或Exception,导致异常结束。
4.当线程在同步代码块、同步代码块中遇到wait()方法的时候,当前线程暂停,就会
  释放锁,让其他线程来操作。
可以查看 线程状态转换图 对照

以下操作不会释放锁:

1.线程执行同步代码块、同步方法时,程序调用Thread.sleep(),Thread.yield方法
  暂停当前线程时执行,不会释放锁。
2.线程执行同步方法、同步代码块时,其他线程调用该线程的suspend方法,将线程挂起,
  该线程不会释放锁。
可以查看 线程状态转换图 对照
线程学习小结,欢迎大家交流学习!
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值