黑马程序员——多线程(下)

lock锁简介

    Lock锁同样可以完成代码同步的任务。
   相较于synchronized方式,Lock锁的出现使同步操作更为灵活。无需使用限制性强的代码块。
   Lock同样为抽象类,需要使用其子类ReentrantLock的对象完成方法调用。
    主要方法:
    public void lock()获取锁
    public void unlock() 释放锁

线程死锁

在多线程的代码编辑过程中,由于考虑得不够周全,会出现死锁的情况。
原因分析:
线程1将锁1锁住,线程2将锁2锁住,而线程1要继续执行锁2中的代码,线程2要继续执行锁1中的代码,但是此时,两个锁均处于锁死状态。最终导致两 线程相
互等待,进入无限等待状态。

有同步代码块的嵌套动作。
解决方法:
不要写同步代码块嵌套

线程死锁代码

-public class DeadLockThreadextends Thread {
-  booleanflag;//定义标记,用来指定要执行的代码
-  publicDeadLockThread(booleanflag) {
-  this.flag =flag;
-  }
-  @Override
-  publicvoid run() {
-  if(flag){//flag赋值为true时,执行的代码
-    synchronized (锁1) {
-  System.out.println("if中锁1");
-  synchronized(锁2) {
-  System.out.println("if中锁2");
-  }
-  }
-  }else {//flag赋值为false时,执行的代码
-    synchronized (锁2) {
-  System.out.println("else中锁2");
-  synchronized(锁1) {
-  System.out.println("else中锁1");
-  }
-  }
-  }
  }

等待唤醒机制

当出现对同一资源的生产与消费时,可以使用多线程完成对同一资源的操作。而消费者需要等待生产者生产后才能消费,生产者也需要等待消费者消费后才能生产。于是出现了生产者消费者问题。这时可以使用等待唤醒机制完成相关需求。

涉及方法:
涉及并非是Thread类的方法,而是Object类的两个方法:因为锁可以为共享数据本身可以是任意的对象,在runnable中进行等待唤醒当前所在线程。
等待:
public final void wait() throws InterruptedException
让当前线程进入等待状态,如果线程进入该状态,不唤醒或打断,不会解除等待状态。
进入等待状态时会释放锁。
唤醒:
public final void notify()
唤醒正在等待的线程。
继续等待之后的代码执行。
sleep与wait的区别:
sleep指定时间,wait可指定可不指定。
sleep释放执行权,不释放锁。因为一定可以醒来。
wait释放执行权与锁。

线程组

多个线程出现时,可以将线程分组,统一处理。
涉及线程组类:ThreadGroup
注意:
线程组可以包含线程或者线程组。
当前线程只能访问所在线程组或者子组。不能访问父组或者兄弟组。
如果没有指定线程组,则属于main线程组。
主要方法:
public final String getName()
public final void setDaemon(boolean daemon)
等其他统一设置方法
无线程添加方法,设置线程组在Thread构造方法中

例设计模式

内存当中只存在一个实例对象。
单例设计模式要求。
构造方法私有化
定义了自己类型的静态私有成员变量
对外提供公共的、静态的获取实例方法
实例创建方式分为懒汉式与饿汉式
懒汉式时,需要考虑线程安全问题

懒汉式:
class Single{
private static Single s = null;
private Single(){}
public static Single getIntance(){
if (s == null){
s = new Single();
}
return s;
}
}
饿汉式:
class Single{
private static Single s = new Single();
private Single(){}
public static Single getIntance(){
return s;
}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
黑马程序员多线程练习题主要包括两个问题。第一个问题是如何控制四个线程在打印log之前能够同时开始等待1秒钟。一种解决思路是在线程的run方法中调用parseLog方法,并使用Thread.sleep方法让线程等待1秒钟。另一种解决思路是使用线程池,将线程数量固定为4个,并将每个调用parseLog方法的语句封装为一个Runnable对象,然后提交到线程池中。这样可以实现一秒钟打印4行日志,4秒钟打印16条日志的需求。 第二个问题是如何修改代码,使得几个线程调用TestDo.doSome(key, value)方法时,如果传递进去的key相等(equals比较为true),则这几个线程应互斥排队输出结果。一种解决方法是使用synchronized关键字来实现线程的互斥排队输出。通过给TestDo.doSome方法添加synchronized关键字,可以确保同一时间只有一个线程能够执行该方法,从而实现线程的互斥输出。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [黑马程序员——多线程10:多线程相关练习](https://blog.csdn.net/axr1985lazy/article/details/48186039)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值