线程基础
来源:互联网 发布:试题软件 编辑:程序博客网 时间:2024/06/05 06:03
Java Thread:
Java 语言的JVM运行程序运行时创建多个线程,它通过java.lang.Thread类来实现
Thread类的特性:
1.每个线程都是通过某个特定Thread对象的run方法来完成操作的,经常把run方法的主体叫做线程体。
2.通过该Thread对象的start()方法来调用这个线程。
3.每个程序至少有一个线程,主线成main
4.守护线程,垃圾回收机制。
创建线程的方式一: extends Thread
创建多线程的第一种方式,继承java.lang.Thread类
- 创建一个继承于Thread的子类
- 重写Thread类的run()方法,在方法内实现子线程要完成的功能
- 创建一个子类对象
- 调用线程的start()方法,启动子线程,调用相应的run方法
线程中常用方法:
currentThread():静态的,当前线程对象
setName():设置线程名称
getName():获取当前线程名称
yield():方法,调用此方法的线程,释放当前CPU的执行权
join():在A线程中调用B线程的join方法,表示当执行到此方法,A线程停止执行,直至B线程执行完毕,A线程再接着执行join方法之后代码。
isAlive():判断当前线程是否存活,返回boolean
sleep(long i):显示的让当前线程睡眠 i 毫秒
线程通信:wait(),notify(),notifyAll()
设置线程优先级:
setPriority(int newPriority):改变线程的优先级
- getPriority():获取线程的优先级
创建多线程的方式二:implements Runnable
创建多线程,实现runnable接口
1.创建一个实现Runnable接口的类
2.实现run方法
3.创建一个实现Runnable接口实现类的对象
4.将这个对象作为形参传递给thread类的构造器中,创建Thread对象,此对象即为一个线程
5.调用start方法启动线程,并执行run方法
创建多线程的两种方式比较:
1.继承方式extend Thread VS 2.实现的方式 implements Runnable
实现接口的方式优于继承的方式。
1.避免了java中单继承的局限性。
2.多个线程,操作共享变量时更适合。
3.需要注意的是,多个线程同时操作共享变量时容易出现线程安全性问题。
线程的分类:
1.守护线程,2.用户线程
1.他们在几乎每个方面都是相同的,唯一的区别时判断JVM何时离开。
2.守护线程是用来服务用户线程的。
通过在start()方法之前调用thread.setDaemon(true),可以把一个用户线程编程一个守护线程
3.java垃圾回收就是一个典型的守护线程。
4.若JVM中都是守护线程,当前JVM将退出。
线程的生命周期:
Thread.State枚举表示了线程的集中状态,5种状态:
1.新建:当一个Thread类或其子类的对象被声明并创建时,新生成的线程对象处于新建状态。2.就绪:处于新建状态的线程被start()后,将进入线程队列等待CPU分配执行权,此时它具备了运行的条件。3.运行:当就绪的线程得到CPU的执行权,便进入运行状态,执行run方法中的操作。4.阻塞:在某种特殊情况下,被人为挂起或执行输入输出操作时,让出CPU执行权并临时中止自己的执行。5.死亡:线程完成了它的全部工作或线程被提前强制性的中止。
关于单例模式中懒汉式的线程安全问题:使用同步机制
/ * * 对于一般的方法内,使用同步代码块,可以考虑使用this * 对于静态方法而言,使用当前类本身充当锁: 当前类名.class */class Singleton{ private static Singleton single=null; private Singleton(){} public static Singleton getInstance(){ if(single==null){//双重判断 synchronized (Singleton.class) { if(single==null){ single= new Singleton(); } } } return single; }}public class TestSingleton { public static void main(String[] args) { Singleton s1=Singleton.getInstance(); Singleton s2=Singleton.getInstance(); System.out.println(s1==s2); }}
线程的死锁:
死锁例子:
public class TestDeadLock {static StringBuffer s1=new StringBuffer();static StringBuffer s2=new StringBuffer(); public static void main(String[] args) { new Thread(){ public void run() { synchronized (s1) { try { Thread.currentThread().sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } s1.append("A"); synchronized (s2) { s2.append("B"); System.out.println(s1); System.out.println(s2); } } } }.start(); new Thread() { public void run() { synchronized (s2) { try { Thread.currentThread().sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } s1.append("C"); synchronized (s1) { s2.append("B"); System.out.println(s1); System.out.println(s2); } } } }.start(); }}
线程通信:
1.read 和 load 阶段:线程从主内存复制变量到当前线程工作内存。
2.use 和 asign 阶段:执行代码,改变共享变量值。
3.store 和 write 阶段:用工作内存数据刷新主内存对应变量的值。
在多线程环境下,use 和 asign 是多次出现的,不具备原子性。即工作内存与主内存变量不同步,从而导致非线程安全问题。
voliate 关键字解决的是变量读取时的可见性问题,但无法保证变量的原子性。对于多个线程访问同一个实例变量还是需要加锁同步。
sleep 与 wait 的区别?
1.这两个方法来自不同的类分别是Thread和Object
2.最主要是sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
3.wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在 任何地方使用
synchronized(x){ x.notify() //或者wait() }
4.sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
另外注意:wait()方法立即释放锁,而notify()方法执行后,并不立即释放锁,而是notif()所做synchronized同步代码块执行完毕后才释放锁。
wait():方法可以使调用该方法的线程释放共享资源的锁,然后从运行状态退出,进入等待队列,直到被再次唤醒。
notify():方法可以随机唤醒等待队列中等待同一共享资源的“一个”线程,使得该线程退出等待队列,进入运行状态。即:notify()
方法仅通知“一个”线程。
notifyAll():方法可以是所有正在等待队列中等待同一共享资源的“全部”线程从等待状态退出,进入可运行状态。此时他们共同抢占cpu资源,一般来说优先级高的先执行。
线程释放锁的情况?
1.执行完同步代码块就会释放对象的锁。
2.在执行同步代码块的过程中,遇到异常而导致线程终止,锁也会被释放。
3.在执行同步代码块的过程中,执行了锁对象的wait()方法也会释放锁。
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- 线程基础
- GemFire 入门篇2:GemFire 8.2 在CentOS & Mac OS X的安装步骤
- JavaScript使用接口
- numpy 学习2
- Android 系列 3.1设置Android虚拟设备(AVD)进行应用程序测试
- Leetcode Binary Search Tree Iterator
- 线程基础
- 大型网站应用之海量数据和高并发解决方案总结一二
- yum解决Error: Cannot find a valid baseurl for repo: base
- idea mybatis generator
- Android 修改HOSTS解决办法,android下修改hosts文件不起作用(无效)的解决办法
- java nio 异步操作 (一)
- 【汇编】计算机寄存器介绍
- Android Studio----- 无法打印---log----问题总结----华为坑深
- 触发器