Java多线程(一):
https://blog.csdn.net/Veer_c/article/details/103842078
Java多线程(二):
https://blog.csdn.net/Veer_c/article/details/103842263
Java多线程(三):
https://blog.csdn.net/Veer_c/article/details/103842317
Java多线程(四):
https://blog.csdn.net/Veer_c/article/details/103842602java
案例:利用匿名内部类,启动多个线程,验证单例设计模式之懒汉式所存在的缺陷,web
public class SingleIntanceDemo { //私有化构造 private SingleIntanceDemo(){} private static SingleIntanceDemo instance = null; public static SingleIntanceDemo getInstance(){ try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } if (instance==null) { instance = new SingleIntanceDemo(); } return instance; } } public class Test { public static void main(String[] args) { //启动第一个线程 new Thread(){ @Override public void run() { System.out.println(SingleIntanceDemo.getInstance()); //com.edu_12.SingleIntanceDemo@2d7fc1e7 } }.start(); //启动第二个线程 new Thread(){ public void run() { System.out.println(SingleIntanceDemo.getInstance()); //com.edu_12.SingleIntanceDemo@2a8b83e3 }; }.start(); } }
当咱们利用多线程来验证单例模式的时候,发现俩个对象的地址值不一样,即不是同一个对象,咱们能够利用同步方法来改进
在建立对象的方法上加上 synchronized关键字就能够
(9)JDK5的Lock锁,咱们以前造的全部的锁都没有手动释放锁
static Lock lock = new ReentrantLock();
上枷锁:lock.lock();
释放锁:lock.unlock();
能够让咱们明确的知道在哪里加锁和释放锁。
依然写一个卖票的案例,用lock枷锁释放锁,
为了保证咱们建立的锁必定会被释放,用一下代码进行改进
try{….}finally{……}设计模式
public class MyThread implements Runnable{ //定义100张票 int ticket = 100; Object obj = new Object(); //建立一个锁 Lock lock = new ReentrantLock(); @Override public void run() { while (true) { try{ //加上锁,获取锁 lock.lock(); if (ticket>0) { //考虑到实际的生活中,咱们须要给每个线程加入必定的延迟,模拟一下这种效果 try { Thread.sleep(100); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println(Thread.currentThread().getName()+"正在出售第:"+ticket--+"张票"); } }finally{ //这里面的代码必定会被执行 //释放锁 lock.unlock(); } } } } public class Test { public static void main(String[] args) { //建立MyThread对象 MyThread mt = new MyThread(); //建立三个窗口 Thread t1 = new Thread(mt); Thread t2 = new Thread(mt); Thread t3 = new Thread(mt); //给每个窗口设置姓名 t1.setName("窗口一"); t2.setName("窗口二"); t3.setName("窗口三"); //开启窗口进行售票 t1.start(); t2.start(); t3.start(); } }
死锁问题:
同步嵌套,锁里面套了一个锁,出现同步嵌套多线程
package com.edu_14; public class DieThread extends Thread{ boolean flag; //提供一个有参构造 public DieThread(boolean flag){ this.flag = flag; } @Override public void run() { if (flag) { synchronized (MyLock.objA) { System.out.println("if"+"objA"); synchronized (MyLock.objB) { System.out.println("if"+"objB"); } } }else { synchronized (MyLock.objB) { System.out.println("else"+"objB"); synchronized (MyLock.objA) { System.out.println("else"+"objA"); } } } } } package com.edu_14; public abstract class MyLock { //定义两个锁 public static final Object objA = new Object(); public static final Object objB = new Object(); } package com.edu_14; public class Test { public static void main(String[] args) { //建立两个线程,分别设置不一样的布尔值 DieThread dt = new DieThread(true); DieThread dt2 = new DieThread(false); //开启两个线程 dt.start(); dt2.start(); } }
线程等待和唤醒机制:waitThread,NotifyThread,MyLock,Test
锁对象调用wait() 锁对象调用notify()ide
package com.edu_15; public abstract class MyLock { public static final Object obj = new Object(); } package com.edu_15; public class WaitThread extends Thread{ @Override public void run() { synchronized (MyLock.obj) { //让等待线程处于等待状态 try { MyLock.obj.wait();//当线程处于等待状态的时候,线程就不会继续往下执行了 //线程在处于等待的时候,会释放掉本身手中的锁 //sleep()这个方法,在线程休息的时候会释放锁码? //答:不会 } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } System.out.println("我被唤醒了"); } } package com.edu_15; public class NotifyThread extends Thread{ @Override public void run() { synchronized (MyLock.obj) { //唤醒等待线程 MyLock.obj.notify();//唤醒正在等待的线程,唤醒的等待线程的锁对象,必须和等待线程的锁对象一致 } } } package com.edu_15; /* (11)线程等待和唤醒机制(案例演示:waitThread,NotifyThread,MyLock,Test) 锁对象调用wait():线程的等待 锁对象调用notify():线程的唤醒 * 注意: wait和sleep的区别 线程等待,在等待的同时释放锁,而sleep()方法在执行的过程当中是不会释放锁的 */ 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的区别:
线程等待,在等待的同时释放锁,而sleep()方法在执行的过程当中是不会释放锁的svg
Java多线程(一):
https://blog.csdn.net/Veer_c/article/details/103842078
Java多线程(二):
https://blog.csdn.net/Veer_c/article/details/103842263
Java多线程(三):
https://blog.csdn.net/Veer_c/article/details/103842317
Java多线程(四):
https://blog.csdn.net/Veer_c/article/details/103842602this