黑马程序员——java多线程
来源:互联网 发布:php 5.3 is required 编辑:程序博客网 时间:2024/06/06 09:03
三、创建多线程
public class ThreadTest {public static void main(String[] args) {MyThread myThread = new MyThread();myThread.start();while(true){System.out.println("main()运行");}}}class MyThread extends Thread{public void run(){while(true){System.out.println("mythread运行");}}}
public class ThreadTest2 {public static void main(String[] args) {MyThread myThread = new MyThread();Thread thread = new Thread(myThread);thread.start();while(true){System.out.println("main()运行");}}}class MyThread implements Runnable{public void run(){while(true){System.out.println("run()运行");}}}
四、线程的生命周期
public class ThreadTest3 {public static void main(String[] args) {MyThread2 myThread1 = new MyThread2("t1");MyThread2 myThread2 = new MyThread2("t2");myThread1.start();myThread2.start();}}class MyThread2 extends Thread{MyThread2(String s){super(s);}public void run(){for(int i = 0; i < 1000; i++){System.out.println(getName() + ":" + i);if(i % 10 == 0)yield();}}}
public class SleepThreadTest extends Thread{public void run(){while(true){System.out.println("每隔一秒钟输出一次");try{sleep(1000);}catch(InterruptedExcption e){e.printStackTrace();}}}}
多线程的同步:
多线程并发访问同一个对象(临界资源),如果不对线程进行同步控制,破坏了原子操作(不可再分的操作),则会造成临界资源(两个线程同时访问的资源)的数据不一致。
每一个对象都有一个互斥的锁标记和一个锁池。当线程拥有这个对象的锁标记时才能访问这个资源,没有锁标记便进入锁池,保证在同步代码块中只有一个线程,解决了多线程同步控制的问题。
关键字:synchronized //线程在同步代码中必须采用串行访问
synchronized修饰代码块:对括号内的对象object加锁,只有拿到对象锁标记的线程才能进入该代码块。
publicvoid push(char c){ synchronized(object){ //object只要是对象就可以,但必须保证是同一对象 …… 同步代码 …… } }
synchronized修饰方法:在整个方法范围内对当前对象的加锁,只有拿到对象锁标记的线程才能执行该方法。尽可能的少用
publicsynchronized void push(char c) { …… 同步代码 …… }
一个线程可以同时拥有多个对象的锁标记,锁标记如果过多,就会出现线程等待其他线程释放锁标记,而又都不释放自己的锁标记供其他线程运行的状况,造成死锁。
静态方法可以是同步方法:但是它所锁的并不是当前对象,是类对象。
抽象方法不能是synchronized同步的方法。
构造方法不能是synchronized同步的方法。
线程因为未拿到锁标记而发生阻塞进入锁池(lock pool)。每个对象都有自己的一个锁池的空间,用于放置等待运行的线程。由系统决定哪个线程拿到锁标记并运行
利用Collections类中的synchronizedXxxx(Xxxx ss)方法可以得到相应集合的线程安全的集合
注意:
在同步语句块中不能直接操作对象锁正在使用的对象。
对象与锁一一对应。
同步依赖对象锁,锁对象相同,同步语句串行,锁对象不同,同步语句并行。
顺序锁,不要回调,反向打开。
能不用同步就不用同步,有数据共享冲突时才使用同步。
等待通知机制:
线程间通信使用的空间称之为对象的等待对列(wait pool),该队列也是属于对象的空间的。
使用Object类中wait()的方法,在运行状态中,线程调用wait(),此时表示线程将释放自己所有的锁标记和CPU的占用,同时进入这个对象的等待池。等待池的状态也是阻塞状态,只不过线程释放自己的锁标记。只有在对该对象加锁的同步代码块里,才能掉用该对象的wait(),表示线程将会释放所有锁标记,进入等待队列,线程将进入等待队列状态。
一个线程进入了一个对对象加锁的同步代码块,并对该对象调用了wait()方法,释放自己拥有的所有锁标记,进入该对象等待队列,另一个线程获得了该对象的锁标记,进入代码块对该对象调用了notify()方法,就会从等待队列里释放出一线程,释放出的这个线程要继续运行就还要进入那个同步代码块,因为得不到要访问代码块对象的锁标记,而进入该对象的锁池,等待锁标记释放。
什么情况下释放锁:
同类代码执行完毕。
异常未处理,错误退出。
调用wait()。
相关方法:
1) wait():交出锁和CPU的占用;
2)notify():将从对象的等待池中移走一个任意的线程,并放到锁池中,那里的对象一直在等待,直到可以获得对象的锁标记。
3)notifyAll(): 将从等待池中移走所有等待那个对象的线程并放到锁池中,只有锁池中的线程能获取对象的锁标记,锁标记允许线程从上次因调用wait()而中断的地方开始继续运行
注意:
用notifyAll()取代notify(),因为在调用notify()方法时,是由系统决定释放出哪个线程。
只能对加锁的资源进行wait()和notify()。
判断是否进行等待wait()时,用while代替if来进行判断。
- 黑马程序员—java多线程
- 黑马程序员—JAVA多线程
- 黑马程序员—java多线程
- 黑马程序员—Java多线程
- 黑马程序员—java多线程
- 黑马程序员—Java多线程
- 黑马程序员——Java 多线程
- 黑马程序员——Java多线程锁
- 黑马程序员——JAVA多线程
- 黑马程序员——java多线程
- 黑马程序员——java多线程
- 黑马程序员——Java多线程入门
- 黑马程序员——Java基础---多线程
- 黑马程序员——Java 多线程
- 黑马程序员——【java】多线程
- 黑马程序员——Java多线程
- 黑马程序员——Java基础---多线程
- 黑马程序员——Java多线程
- Ubuntu中安装VBox, VBox中安装 Windwo XP, XP上网总结
- 要搬家了
- 排序算法总结
- c++基础
- C++ Deque容器的使用方法
- 黑马程序员——java多线程
- 解决 Ubuntu 安装 VBox ,但 VBox 中的 XP 无法 FTP 方式访问 Ubuntu
- 数据库范式
- 最长上升子序列
- Android应用程序启动过程源代码分析
- 世界有两棵树
- ICMP协议
- ABAP-模块 字符串操作基础知识
- angularJs HTTP响应拦截器