Java学习笔记(十五)--线程
来源:互联网 发布:nginx 与 keepalive 编辑:程序博客网 时间:2024/05/22 15:30
多线程
1.线程是依赖于进程而存在:
(1)进程:正在运行的应用程序
(2)线程:进程的执行路径,执行单元
2.多线程的两种方案:
(1)继承Thread类;
package com.edu_01;public class MyThread extends Thread{ //1.继承Thread类 //2.重写run方法,重写run方法中的代码之后,当我们启动了这个线程之后,我们的这个线程就会执行run方法中的代码 @Override public void run() { //需求:开启该线程之后,执行一个for循环 for (int i = 0; i < 10; i++) { System.out.println(i); } }}
(2)实现Runnable接口。
package com.edu_01;public class MyThread implements Runnable{ @Override public void run() { //启动该线程对象之后,需要执行的代码 for (int i = 0; i < 10; i++) { System.out.println(i); } }}
3.多线程的几个问题:
(1)启动多线程:start()方法
start()方法的两个作用:
第一:开启一个独立的线程;
第二:让新线程执行run()方法中的代码。
(2)start()和run()的区别:
start():1.开启线程 2.执行run()方法里面的代码
run():执行的是线程里面执行的代码,并不会开启线程
(3)重写run():因为每一个线程需要执行的代码都不一样。
(4)线程不可以多次启动。
4.线程休眠:Thread.sleep(long millis)
:在指定的毫秒数内让当前正在执行的线程休眠(暂停执行)。
5.线程名称:
setName(String name):改变线程名称
getName():返回该线程的名称
6.线程的调度及优先级:
(1)线程的优先级:设置线程抢占CPU的概率(肉眼上,多个线程同时执行,本质上,CPU在一个时间点上只能执行一个任务。)。
(2)setPriority(int newPriority):更改线程的优先级,默认值是5,区间在1-10之间。
多线程安全问题
1.多线程安全问题:
(1)是否是多线程环境;
(2)是否有共享数据;
(3)是否有多条语句操作共享数据。
2.如何解决多线程安全问题:
(1)同步代码块:
synchronized(对象) { 需要被同步的代码。 }
注意三点
第一,对象:任意对象,这个对象就成为锁,只要线程进去就把锁锁上;
第二,需要被同步的代码:会出现线程安全问题的代码;
第三,同步代码块对锁的要求:需要多个线程共享一把锁。
(2)锁对象问题:
A:同步代码块(定义一个抽象类,里面专门定义一个锁):任意对象。
B:同步方法(仅适用于实现Runnable接口):将synchronized关键字加到方法上,同步方法的锁是this。
例如:多线程售票问题。
private synchronized void sellTicket() { //需要同步的代码 if (ticket>0) { //考虑到实际的生活中,我们需要给每一个线程加入一定的延迟,模拟一下这种效果 try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"正在出售第:"+ticket--+"张票"); }}
C:静态同步方法:它的锁是本类的字节码文件对象:类名.class。例如:synchronized (MyThread.class)
private static synchronized void sellTicket() { //需要同步的代码 if (ticket>0) { //考虑到实际的生活中,我们需要给每一个线程加入一定的延迟,模拟一下这种效果 try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"正在出售第:"+ticket--+"张票"); }
匿名内部类的方式使用多线程
1.继承Thread类:
new Thread() { public void run() { ... }}.start();
2.实现Runnable接口:
new Thread(new Runnable(){ public void run() { ... }}).start();
JDK5的Lock锁
1.Lock 实现提供了比使用 synchronized 方法和语句可获得的更广泛的锁定操作。
static Lock lock = new ReentrantLock();lock.lock();//加锁lock.unlock();//释放锁
2.void lock()获取锁。 如果锁不可用,出于线程调度目的,将禁用当前线程,并且在获得锁之前,该线程将一直处于休眠状态。
3.void unlock()释放锁。
4.不使用块结构锁就失去了使用 synchronized 方法和语句时会出现的锁自动释放功能。为了保证我们创建的锁一定会被释放,用以下代码进行改进:
Lock l = ...; l.lock(); try { // access the resource protected by this lock } finally { l.unlock(); }
5.死锁问题:同步嵌套,锁里面套了一个锁,会出现死锁问题,所以以后写代码的过程中尽量避免同步嵌套。
线程等待和唤醒机制
案例:waitThread,NotifyThread,MyLock,Test。
获取锁对象:
package com.edu_01;public abstract class MyLock { public static final Object obj = new Object();}
等待机制:
package com.edu_01;public class WaitThread extends Thread{ @Override public void run() { synchronized (MyLock.obj) { //让等待线程处于等待状态 try { MyLock.obj.wait(); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("我被唤醒了"); }}
唤醒机制:
package com.edu_01;public class NotifyThread extends Thread{ @Override public void run() { synchronized (MyLock.obj) { //唤醒等待线程 MyLock.obj.notify();//唤醒正在等待的线程,唤醒的等待线程的锁对象,必须和等待线程的锁对象一致 } }}
测试类:
package com.edu_01;public class Test { public static void main(String[] args) { //创建等待线程,让等待线程处于一个等待状态 WaitThread wt = new WaitThread(); wt.start(); //睡上5秒钟之后唤醒等待线程 try { Thread.sleep(5000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } //创建唤醒线程对象 NotifyThread nt = new NotifyThread(); nt.start(); }}
wait()和sleep()的区别:
wait():线程等待的过程中,程序不会继续往下执行了,等待的同时会释放掉手中的锁。
sleep():在线程休眠的过程中,不会释放手中的锁。
注意:
唤醒正在等待的线程,唤醒的等待线程的锁对象,必须和等待线程的锁对象一致。
- Java学习笔记(十五)--线程
- java学习笔记(十五)
- Java学习笔记(十五)
- Java学习笔记(十五)
- Java学习笔记(十五)
- java学习笔记(十五)
- Java学习笔记十五
- java学习笔记(二十五)接口
- java学习笔记(十五)继承
- 学习笔记(十五)
- java 从零开始,学习笔记之基础入门<异常>(十五)
- Linux学习笔记(十五)
- 学习笔记(二十五)
- python 学习笔记(十五)
- Android学习笔记(十五)
- java学习笔记(线程)
- java学习笔记<十五>List集合
- JAVA学习笔记(二十五) - 泛型Generic
- Android 5.0 打开Service 出现告警:Service Intent must be explicit
- 初识.net界面程序(10)--连接MYSQL数据库
- SpringBoot相关的知识点
- 用canvas制作表情包
- html 点击复制功能
- Java学习笔记(十五)--线程
- 机器人繁殖
- 170517 逆向-通过堆栈传递函数参数
- 静态路由配置
- 169.n1-banner下方的标题和使用ViewPagerIndicator实现圆点
- Android studio 下OpenCV,NDK,配置
- eclipse配置mybatis 的xml提示
- 递归翻转一个字符串
- T4模板之基础篇