黑马程序员——学习日志7多线程

------- android培训java培训、期待与您交流! ----------





1、多线程

进程:一个正在执行中的程序,每一个进程执行都有一个执行顺序,该顺序是 一个执行路径,或叫一个控制单元。

线程:进程序中的一个独立的控制单元,线程控制着进程的执行。一个进程至少有一个线程。

JVM启动时有一个进程java.exe,该进程至少有一个线程负责java程序的执行,这个线程运行的代码存在于main方法中,该线程叫主线程。

JVM启动时,还有一个负责垃圾回心机制的线程。

多线程的特点:随机性。(谁抢到资源,谁就执行。)

多线程的好处:可使程序中的部分产生同时运行的效果,多线程下载可提高效率。

2、创建线程方式一

子类覆盖父类中的run方法,将线程运行的代码存放在run中。建立子类对象的同时线程也被创建。通过调用start方法开启线程。

3、线程的四种状态

      被创建

      运行:由start()开始运行

      冻结:sleep()和wait()开启,sleep()时间到或者notify()结束冻结

      消亡:stop()和run()结束

      特殊的一个状态:具备了执行资格,但还没有获取资源。

4、线程常用方法

currentThread:静态方法,用来获取当前线程

getName、setName:用来获取、设置当前线程的名字

sleep控制线程休眠,单位为毫秒

setDeamon:将线程设置为守护线程。线程默认是非守护线程,守护线程不能单独执行

join:当前线程暂停,等待加入的线程运行结束,当前线程继续执行

5、第二种方法:实现Runnable接口

子类覆盖接口中的run方法。通过Thread类创建线程,并将实现了Runnable接口的子类对象作为参数传递给Thread类的构造函数。Thread类对象调用start方法开启线程

6、多线程的安全问题

多线程并发访问同一数据,有可能出现线程安全问题。一条线程的访问还没有结束,CPU切换到另一条线程工作,导致数据访问出错。

格式:synchronized(对象)

{

需要同步的代码;

}

同步可以解决安全问题的根本原因就在那个对象上。该对象如同锁的功能。

同步的前提:同步需要两个或者两个以上的线程。多个线程使用的是同一个锁

同步的弊端:当线程相当多时,因为每个线程都会去判断同步上的锁,这是很耗费资源的,无形中会降低程序的运行效率。

同步方法:使用同步方法,用synchronized修饰方法,整个方法的代码都是同步的,只能一个线程运行。同步方法使用this作为锁。静态同步函数用的锁是class对象

死锁:在多个线程并发执行使用多个锁来同步时,有可能互相冲突,导致程序无法继续执行

简单写就是:synchronized(锁a){ synchronized(锁b)执行代码}

       synchronized(锁b){ synchronized (锁a)执行代码}

当两个线程运行上面两个代码会出现死锁。

7、多线程通信

在同步代码中可以使用锁对象的wait()方法让当前线程等待;使用锁对象的notify()方法可以将正在等待的线程唤醒;如果多个线程都在等待,notify()唤醒随机1个;notifyAll()方法可以唤醒所有在等待的线程。

8、JDK5之后的线程同步与通信

同步:使用java.util.concurrent.locks.Lock接口的实现类对象来进行同步,ReentrantLock就是Lock的实现类,可以实现synchronized的功能在需要同步的代码块后使用lock()和unlock()方法来完成同步unlock()最好放在finally中,因为如果上面代码抛出异常没有解锁的话,会导致其他线程无法运行,程序卡死

通信:使用Lock对象的newCondition()方法获取一个Condition对象,Condition对象可以控制指定线程的等待与唤醒。await()方法可以控制线程等待。signal()方法可以唤醒等待的线程。signalAll()方法可以唤醒所有等待线程

9、停止线程

定义循环结束标记:因为线程运行代码一般都是循环,只要控制了循环即可

使用interrupt(中断)方法,该方法是结束线程的冻结状态,使线程回到运行状态中来

注:stop方法已经过时不再使用

10、String对象

      字符串是一个特殊的对象;字符串一旦初始化就不可以被改变。

      String s1 = “abc”;String s2=newString(“abc”):s1==s2错误,s1equels(s2)正确;s1,s2有什么区别,s1内存中有一个对象,s2有两个对象。

11、String中方法

获取:获取长度:int length();根据位置获取字符:char charAt(int index);根据字符获取位置:int indexOf(int ch):返回ch在字符串中第一次出现的位置。int indexOf(int ch,int fromIndex):从fromIndex指定位置开始,获取ch在字符串中出现的位置。intindexOf(String str):返回str在字符串中第一次出现的位置。intindexOf(String str,int fromIndex):从fromIndex指定位置开始,获取str在字符串中出现的位置int lastIndexOf(intch):返回字符在字符串中最后一次出现的索引位置。

判断:字符串中是否包含某一个子串:boolean contains(str);字符串中是否有内容:boolean isEmpty();字符串是否是以指定内容开头:boolean startsWith(str);字符串是否是以指定内容结尾:boolean endsWith(str);判断字符串内容是否相同(复写Object类中的equals方法):boolean equals(str);判断内容是否相同并忽略大小写:boolean equalsIgnoreCase()

转换:

将字符数组转成字符串:

构造函数:String(char[])
                 String(char[],offset,count)//将字符数组中的一部分转成字符串

静态方法:static String copyValueOf(char[]);static String copyValueOf(char[] data,intoffset,int count);static String valueOf(char[])

将字符串转成字符数组:char[] toCharArray()

将字节数组转成字符串:String(byte[]);String(byte[],offset,count)

将字符串转成字节数组:byte[] getBytes()

将基本数据类型转成字符串:static String valueOf(int);static String valueOf(double)

注:3+"" <==> String.valueOf(3);

字符串和字节数组在转换过程中,是可以指定编码表的。

替换:String replace(oldChar,newChar);Stringreplace(charSequence target,charSequence replacem):替换字符串

切割:String[] split(regex)

获取子串:String substring(begin);String substring(begin,end)

将字符串转成大写或小写:String toUpperCase();StringtoLowerCase();

将字符串两端的多个空格去除:String trim();

对两个字符串进行自然顺序的比较:int compareTo(String);

12、StringBuffer

字符串的组成原理就是通过该类实现的。StringBuffer可以对字符串内容进行增删。StringBuffer是一个容器。很多方法与String相同。StingBuffer是可变长度的

特有方法:StringBuffer append(intx);StringBuffer  delete(int start,int end );StringBuffer  insert(intindex,String str);StringBuffer  reverse();

JDK1.5出现一个StringBuilder,区别是StringBuffer是同步的,StringBuilder是非同步的

13、基本数据类型包装类

      将基本数据类型封装成对象的好处在于可以在对象中定义更多的功能方法操作该数据。

      常用的操作之一:用于基本数据类型与字符串之间的转换。Integer的parseInt方法,intValue方法

JDK1.5以后,简化了定义方式。

Integer x = new Integer(4);可以直接写成

Integer x = 4;//自动装箱。

x  = x + 5;//自动拆箱。通过intValue方法。

需要注意:

在使用时,Integer x = null;上面的代码就会出现NullPointerException

 

 





------- android培训java培训、期待与您交流! ----------

 

  • 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、付费专栏及课程。

余额充值