java基础专栏—ThreadSafe
2017-10-21 00:00
148 查看
摘要: 笔者在java学习的这条道路上也是断断续续走了一年多了,视频啊,书籍啊什么的也看了好几遍了,真的是java从入门到放弃啊,哈哈,看的多了一渐渐的明白了一点东西,笔者整理了一些自己的学习笔记,在此与大家分享,不喜勿喷,多多指教,万分感谢。
同步代码块解决线程问题:
没有锁的线程不能执行只能等待,遇见同步代码块,
判断对象锁还有没有
有,拿走,等执行完成才放回去
没有就只有等
将线程共享部分抽取出来
确保锁唯一
构造方法私有,只能通过静态方法来调用,且不可修改
public void wait()释放正在执行的线程的执行权,放到存储池
public void notify()唤醒在线程池中wait()的线程,一次唤醒一个,而且是任意的。
public void notifyAll(),唤醒在线程池中所有的wait()线程唤醒
[x] 线程之间是不是所有的数据都锁上了
[x] 是不是用的同一个锁
==所有的线程的等待唤醒必须是锁对象调用,调用者是谁?任何方法都需要被调用,本类线程类是没有wait方法的,只有调用父类的super(),但是父类也没有这个方法,调用这个的锁对象是谁就由谁来调用,所以,同步的等待唤醒方法都是Object类的方法==
ThreadSafe
多线程并发
public class Tickets implements Runnable{ private int ticket = 100; public void run(){ while(true){ if(ticket > 0){ System.out.println(Thread.currentThread().getName() + "出售票" + ticket--); } } } } pubilc static void main(String[] args){ Tickets ts = new Ticket(); Thread t0 = new Thread(ts); Thread t1 = new Thread(ts); Thread t2 = new Thread(ts); t0.start(); t1.start(); t2.start(); }
同步代码块解决线程问题:
synchronized(Object obj){线程要操作的代码块}
private Object obj = new Object(); public void run(){ while(true){ synchronized(obj){ if(ticket > 0){ System.out.println(Thread.currentThread().getName() + "出售票" + ticket--); } } } }
同步对象:任意对象,对象监听器
没有锁的线程不能执行只能等待,遇见同步代码块,
判断对象锁还有没有
有,拿走,等执行完成才放回去
没有就只有等
将线程共享部分抽取出来
private int ticket = 100; public void run(){ while(true){ pay(); } } } public static synchronized void pay(){ if(ticket > 0){] System.out.println(Thread.currentThread().getName() + "出售票" + ticket--); } //在同步方法中,对象锁是this。但是在静态方法中,对象锁不是this,this属于对象,优先于static,是本类自己.class
Lock
在线程中,只有出了同步代码块才会释放对象锁,但是要是出现了异常就不会释放了。所以在jdk5以后就使用Lock接口
public void lock() public void unlock()
死锁问题
锁的嵌套出现了互锁
确保锁唯一
构造方法私有,只能通过静态方法来调用,且不可修改
public class lockA{ public static final LockA lockA = new LockA(); private LockA(){ } } public class lockB{ public static final LockB lockB = new LockB(); private LockB(){ } } public class DeadLock implements Runnable{ private int i = 0; public void run(){ while(ture){ if(i%2 == 0){ //先进入A同步,在进入B同步 synchronized(LockA.locka){ System.out.println("if...locka"); synchronized(LockB.lockb){ System.out.println("else...lockb"); } } }else{ synchronized(LockB.lockb){ System.out.println("if...lockb"); synchronized(LockA.locka){ System.out.println("else...locka"); } } } } } }
线程间通信
多个线程操作同一个数据,但是操作的动作可能并不相同,通过一定的手段将各个线程有效的利用,既--等待唤醒机制public void wait()释放正在执行的线程的执行权,放到存储池
public void notify()唤醒在线程池中wait()的线程,一次唤醒一个,而且是任意的。
public void notifyAll(),唤醒在线程池中所有的wait()线程唤醒
[x] 线程之间是不是所有的数据都锁上了
[x] 是不是用的同一个锁
public class Resource{ public String name; public String sex; public boolean flag;//唤醒标识 public Resource(String name,String sex){ this.name = name; } } public class InputThread implements Runnable{ private Resource r = null; public InputThread(Resource r){ this.r = r; } public void run(){ int i = 0; while(true){ synchronized(r){ if(r.flag){ try{ //必须是锁对象调用 r.wait(); }catch(Exception ex){ System.out.println(ex.getMessage()); } } if(i%2 == 0){ r.name = "张三"; r.sex = "男"; }else{ r.name = "lisi"; r.sex = "nv"; } i++; //执行完成,将标识修改,并唤醒对方。 r.flag = true; r.notify(); } } } } public class OutputThread{ private Resource r = null; public void run(){ //使用同一个对象锁 synchronized(r){ while(true){ if(r.flag){ try{ //必须是锁对象调用 r.wait(); }catch(Exception ex){ System.out.println(ex.getMessage()); } System.out.println(r.name); //执行完成,将标识修改,并唤醒对方。 r.flag = false; r.notify(); } } } public OutputThread(Resource r){ this.r = r; } } public class ThreadDemo{ public static void main(String[] args){ Resource r = new Resource(); InputThread int = new InputThread(r); OutputThread outt = new OutputThread(r); Thread in = new Thread(in); Thread out = new Thread(out); } }
为什么是Object的方法
对于线程来说,要同步必须操作同一个锁对象才可以,如果是使用各自来做自己的线程唤醒对象就不能实现
同一个锁对象,并且对于实现类来说,调用者是谁?
==所有的线程的等待唤醒必须是锁对象调用,调用者是谁?任何方法都需要被调用,本类线程类是没有wait方法的,只有调用父类的super(),但是父类也没有这个方法,调用这个的锁对象是谁就由谁来调用,所以,同步的等待唤醒方法都是Object类的方法==
相关文章推荐
- java基础专栏—ArrayFrame(1)
- java基础专栏—JDBC
- java基础专栏—DBUtils(2)
- 面试专栏:算法与数据结构,虚拟机,Java基础,JavaWeb
- java基础专栏—DB(1)
- java基础专栏—Exception
- java基础专栏—Thread
- java基础专栏—IOUtils(4)
- java基础专栏—Properties
- java基础专栏—IO转换(3)
- java基础专栏—IOBuffer(2)
- java基础专栏—IO(1)
- java基础专栏—CommonApi
- java基础专栏—java网络编程
- java基础专栏—ArrayFrame(2)
- java 文件传输基础
- Java 基础练习之数组
- JAVA学习笔记 基础篇
- java基础简介
- Java框架基础——反射(reflect)