java复习并发
2016-01-06 14:37
603 查看
java复习二
想复习一下Java并发,看 Java 特种兵 并发部分 感觉讲的不错,写一下读书笔记两个使用线程的方法
实现Runnable接口的多线程package myList; public class threadtest { public static void main(String[] args) { ThreadTests ds1 = new ThreadTests("阿三"); ThreadTests ds2 = new ThreadTests("李四"); Thread t1 = new Thread(ds1); Thread t2 = new Thread(ds2); t1.start(); t2.start(); } } class ThreadTests implements Runnable { private String name; public ThreadTests(String name) { this.name = name; } public void run() { for (int i = 0; i < 5; i++) { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(name + ": " + i); } } } //李四: 0 阿三: 0 李四: 1 阿三: 1 阿三: 2 李四: 2 李四: 3 阿三: 3 阿三: 4 李四: 4
2.扩展Thread类实现的多线程
package myList; public class TestThread extends Thread { public TestThread(String name) { super(name); } public void run() { for(int i = 0;i<5;i++){ try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(this.getName()+" :"+i); } } public static void main(String[] args) { Thread t1 = new TestThread("阿三"); Thread t2 = new TestThread("李四"); t1.start(); t2.start(); } } //李四 :0 阿三 :0 李四 :1 阿三 :1 阿三 :2 李四 :2 阿三 :3 李四 :3 阿三 :4 李四 :4
new Thread()操作没有完成对线程的创建,只有当调用start()方法时才会真正在系统中存在一个线程,Thread本身对应的实例只是JVM内一个普通Java对象,是一个线程操作的外壳,而不是真正的线程。
线程状态
1.NEW 状态表示线程还没有启动,只是创建了一个Java外壳,要注意的是调用了start()方法不表示状态就立即改变。
2.RUNNABLE 状态
程序运行状态,任务也有可能处于等待状态
3.BLOCKED 状态
BLOCKED称为阻塞状态,原因通常是它在等待一个锁
4.WAITING 状态
通常是指一个线程拥有对象锁后进入到相应的代码区域后,调用相应的锁对象的wait()方法操作后产生的一种结果,与BLOCKED状态比较,BOLOCKED状态是虚拟机认为程序还不能进入某个区域,发生wait()操作的条件就是要进入临界区,只是还有一些其他配合的资源没有准备充分,所有产生了等待。
notify()方法是唤醒一个处于WAITING状态的线程
5.TIMED_WAITING 状态
Thread.sleep()就可以进入TIMED_WAITING状态
6.TERMINATED 状态
线程结束时的状态,run()方法执行完成
wait()与notify()
它们都使用synchronized,它们的实现是基于对象,interrupt()
interrupt()操作在线程处于BLOCKEN, RUNNING状态没有作用,只对WAITING, TIME_WAITING状态的线程有用,让它们产生异常还可以通过isInterrupt()判断线程是否已经被调用过中断方法
stop()与interrupt()
interrupt()是相对缓和的处理方式,stop()对处于RUNNING状态的任务会导致任务直接抛出java.lang.ThreadDeath的Error,会有一定的风险。线程优先级
Java提供了1-10个优先级,理论上数字越大优先级越高可以通过setPriority()来设置优先级
在JVM中还有一种特殊的后台线程,可以通过setDaemon(boolean)设置是否为后台线程,它通常优先级很低,JVM的GC线程就是后台线程,后台线程有一种很重要的的特征,如果JVM进程中活着的线程只有后台线程,就要结束整个进程。
线程合并(Join)
package myList; class ThreadTesterA implements Runnable { private int counter; @Override public void run() { while (counter <= 10) { System.out.print("Counter = " + counter + " "); counter++; } System.out.println(); } } class ThreadTesterB implements Runnable { private int i; @Override public void run() { while (i <= 10) { System.out.print("i = " + i + " "); i++; } System.out.println(); } } public class ThreadTester { public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(new ThreadTesterA()); Thread t2 = new Thread(new ThreadTesterB()); t1.start(); t1.join(); // wait t1 to be finished t2.start(); t2.join(); // in this program, this may be removed } } //i = 0 Counter = 0 Counter = 1 i = 1 Counter = 2 i = 2 Counter = 3 i = 3 Counter = 4 Counter = 5 Counter = 6 Counter = 7 Counter = 8 Counter = 9 Counter = 10 i = 4 i = 5 i = 6 i = 7 i = 8 i = 9 i = 10
可以实现同步的作用
线程安全
一致性问题一般出现在多核机器上package myList; public class ThreadTest extends Thread{ private boolean ready; private int number; public void run(){ while(!ready){ number++; } System.out.println(ready); } public void readyOn(){ this.ready = true; } public static void main(String [] args){ ThreadTest readThread = new ThreadTest(); readThread.start(); try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } readThread.readyOn(); System.out.println(readThread.ready); } }
代码可能会不能停止,因为不同变量的修改不需要立即写回到主存,而线程读取也不需要每一次去读取数据。
解决方法:1.在循环中添加一个Thread.yield(),操作就可以让线程让步CPU,进而很可能到主存中读取最新的ready的值。2.在循环中加一条System.out语句,或者将ready变量增加一个volatile修饰符也可以达到退出的目的。
ThreadLocal
ThreadLocal可以放一个线程级别的变量,但它本身可以被多个线程共享使用,而又达到线程安全的目的,且绝对线程安全。public final static ThreadLocal<String> RESOURCE = new ThreadLocal<String>();
RESOURCE代表一个可以存放String类型的ThreadLocal对象,任何一个线程可以并发访问这个变量,对它进行写入,读取操作,都是线程安全的
原子性和锁
synchronizedsynchronized通过在对象上加锁后进入临界区达到临界区串行访问的目的
1.普通方法前面加synchronized
synchronized public void test() {}
锁住了类的对象
2. 静态方法前面加synchronized
synchronized public static void test() {}
锁住了当前类
3. 代码块加锁
synchronized(object){ //代码 }
锁住的不是代码而是object对象
相关文章推荐
- java对世界各个时区(TimeZone)的通用转换处理方法(转载)
- java-注解annotation
- java-模拟tomcat服务器
- java-用HttpURLConnection发送Http请求.
- java-WEB中的监听器Lisener
- Android IPC进程间通讯机制
- Android Native 绘图方法
- Android java 与 javascript互访(相互调用)的方法例子
- Python3写爬虫(四)多线程实现数据爬取
- 介绍一款信息管理系统的开源框架---jeecg
- 聚类算法之kmeans算法java版本
- java实现 PageRank算法
- PropertyChangeListener简单理解
- c++11 + SDL2 + ffmpeg +OpenAL + java = Android播放器
- 插入排序
- 冒泡排序
- 堆排序
- 快速排序