线程同步与锁定_synchronized_单例模式_doubleChecking_生产者消费者模式_信号灯法_管程法_任务调度_多线程总结

同步:并发 多个线程访问同一份资源 确保资源安全 -->线程安全
synchronized -->同步 (一把锁)

一、同步块
synchronized(引用类型|this|类.class){

}
二、同步方法
synchronized

package com.bjsxt.thread.syn;


public class SynDemo01 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		//真实角色
		Web12306 web= new Web12306();
		//代理
		Thread t1 =new Thread(web,"路人甲");
		Thread t2 =new Thread(web,"黄牛已");
		Thread t3 =new Thread(web,"攻城师");
		//启动线程
		t1.start();
		t2.start();
		t3.start();
		
		
		
		
	}

}



/**
 * 线程安全的类
 * @author Administrator
 *
 */
class Web12306 implements Runnable {
	private int num =10;
	private boolean flag =true;
	@Override
	public void run() {
		while(flag){
			test5();
		}
	}
	
	public void test6(){
	   	
		if(num<=0){
			flag=false; //跳出循环
			return ;
		}
		 //a  b  c 	
		synchronized(this){
			try {
				Thread.sleep(500); //模拟 延时
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
		}
	}
	
	//线程不安全  锁定资源不正确
	public void test5(){
		//a  b  c
		synchronized((Integer)num){
			if(num<=0){
				flag=false; //跳出循环
				return ;
			}
			try {
				Thread.sleep(500); //模拟 延时
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
		}
	}
	
	
	
	//锁定范围不正确 线程不安全
	public void test4(){
		//   c  1
		synchronized(this){
			//b
			if(num<=0){
				flag=false; //跳出循环
				return ;
			}
		}
		// b
		try {
			Thread.sleep(500); //模拟 延时
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
	}//a -->1
	
	
	
	//线程安全  锁定正确
	public void test3(){
		//a  b  c
		synchronized(this){
			if(num<=0){
				flag=false; //跳出循环
				return ;
			}
			try {
				Thread.sleep(500); //模拟 延时
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
		}
	}
	//线程安全  锁定正确
	public synchronized void test2(){
		if(num<=0){
			flag=false; //跳出循环
			return ;
		}
		try {
			Thread.sleep(500); //模拟 延时
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
	}
	
	
	//线程不安全
	public void test1(){
		if(num<=0){
			flag=false; //跳出循环
			return ;
		}
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println(Thread.currentThread().getName()+"抢到了"+num--);
	}
}

package com.bjsxt.thread.syn;
/**
 * 单例设计模式:确保一个类只有一个对象
 * @author Administrator
 *
 */
public class SynDemo02 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		JvmThread thread1 = new JvmThread(100);
		JvmThread thread2 = new JvmThread(500);
		thread1.start();
		thread2.start();
		
	}

}
class JvmThread extends Thread{
	private long time;
	public JvmThread() {
	}
	public JvmThread(long time) {
		this.time =time;
	}
	@Override
	public void run() {		
		System.out.println(Thread.currentThread().getName()+"-->创建:"+Jvm.getInstance(time));
	}
}


/**
 * 单例设计模式
 * 确保一个类只有一个对象
 * 懒汉式  double checking
 * 1、构造器私有化,避免外部直接创建对象
 * 2、声明一个私有的静态变量
 * 3、创建一个对外的公共的静态方法 访问该变量,如果变量没有对象,创建该对象
 */
class Jvm {
	//声明一个私有的静态变量
	private static Jvm instance =null;	
	//构造器私有化,避免外部直接创建对象
	private Jvm(){
		
	}
	//创建一个对外的公共的静态方法 访问该变量,如果变量没有对象,创建该对象
	public static Jvm getInstance(long time){
		// c d e  -->效率  提供 已经存在对象的访问效率
		if(null==instance){	
			// a b
			synchronized(Jvm.class){
				if(null==instance ){
					try {
						Thread.sleep(time); //延时 ,放大错误
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					instance =new Jvm();
				}
			}
	  }//a
	  return instance;
	}
	
	
	public static Jvm getInstance3(long time){
		//a b c d e  -->效率不高 c  存在对象也需要等待
		synchronized(Jvm.class){
			if(null==instance ){
				try {
					Thread.sleep(time); //延时 ,放大错误
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				instance =new Jvm();
			}
			return instance;
		}
	}
	
	
	public static synchronized Jvm getInstance2(long time){
		if(null==instance ){
			try {
				Thread.sleep(time); //延时 ,放大错误
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			instance =new Jvm();
		}
		return instance;
	}
	
	
	
	public static Jvm getInstance1(long time){
		if(null==instance ){
			try {
				Thread.sleep(time); //延时 ,放大错误
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			instance =new Jvm();
		}
		return instance;
	}
}
package com.bjsxt.thread.syn;
/**
 * 单例创建的方式
 * 1、懒汉式
 * 1)、构造器私有化
 * 2)、声明私有的静态属性
 * 3)、对外提供访问属性的静态方法,确保该对象存在
 * 
 * @author Administrator
 *
 */
public class MyJvm {
	private static MyJvm instance;
	private MyJvm(){
		
	}
	public static MyJvm getInstance (){
		if(null==instance){ //提供效率
			synchronized(MyJvm.class){
				if(null==instance){ //安全
					instance =new MyJvm();
				}
			}
		}
		return instance;
	}
	

}
/**
 * 饿汉式
   1)、构造器私有化 
 * 2)、声明私有的静态属性,同时创建该对象
 * 3)、对外提供访问属性的静态方法
 * @author Administrator
 *
 */
class MyJvm2 {
	private static MyJvm2 instance =new MyJvm2();
	private MyJvm2(){
		
	}
	public static MyJvm2 getInstance (){		
		return instance;
	}

}
/**
 * 类在使用的时候加载 ,延缓加载时间
 * @author Administrator
 *
 */
class MyJvm3 {
	private static class JVMholder{
		private static MyJvm3 instance =new MyJvm3();
	}
	private MyJvm3(){
		
	}
	public static MyJvm3 getInstance (){		
		return JVMholder.instance;
	}

}

三、死锁: 过多的同步容易造成死锁

package com.bjsxt.thread.syn;
/**
 * 过多的同步方法可能造成死锁
 * @author Administrator
 *
 */
public class SynDemo03 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Object g =new Object();
		Object m = new Object();
		Test t1 =new Test(g,m);
		Test2 t2 = new Test2(g,m);
		Thread proxy = new Thread(t1);
		Thread proxy2 = new Thread(t2);
		proxy.start();
		proxy2.start();
	}

}
class Test implements Runnable{
	Object goods ;
	Object money ;
	
	public Test(Object goods, Object money) {
		super();
		this.goods = goods;
		this.money = money;
	}

	@Override
	public void run() {
		while(true){
			test();
		}
	}
	
	public void test(){
		synchronized(goods){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			synchronized(money){
				
			}
			
		}
		System.out.println("一手给钱");
	}
	
	
	
	
	
	
	
}

class Test2  implements Runnable{
	Object goods ;
	Object money ;
	public Test2(Object goods, Object money) {
		super();
		this.goods = goods;
		this.money = money;
	}

	@Override
	public void run() {
		while(true){
			test();
		}
	}
	
	public void test(){
		synchronized(money){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			synchronized(goods){
				
			}
			
		}
		System.out.println("一手给货");
	}
	
	
	
}




线程同步与锁定_synchronized_单例模式_doubleChecking_生产者消费者模式_信号灯法_管程法_任务调度_多线程总结_第1张图片
信号灯法
一、 wait() :等待,释放锁 sleep 不释放锁
二、notify()/notifyAll():唤醒
与 synchronized 一起使用

package com.bjsxt.thread.pro;
/**
 * 生产者
 * @author Administrator
 *
 */
public class Player implements Runnable {
	private Movie m ;
	
	public Player(Movie m) {
		super();
		this.m = m;
	}

	@Override
	public void run() {
		for(int i=0;i<20;i++){
			if(0==i%2){
				m.play("左青龙");
			}else{
				m.play("右白虎");
			}
		}
	}

}

package com.bjsxt.thread.pro;

public class Watcher implements Runnable {
	private Movie m ;
	
	public Watcher(Movie m) {
		super();
		this.m = m;
	}

	@Override
	public void run() {
		for(int i=0;i<20;i++){
			m.watch();
		}
	}

}

package com.bjsxt.thread.pro;
/**
 一个场景,共同的资源
  生产者消费者模式 信号灯法
 wait() :等待,释放锁   sleep 不释放锁
 notify()/notifyAll():唤醒
  与 synchronized
 * @author Administrator
 *
 */
public class Movie {
	private String pic ;
	//信号灯
	//flag -->T 生产生产,消费者等待 ,生产完成后通知消费
	//flag -->F 消费者消费 生产者等待, 消费完成后通知生产
	private boolean flag =true;
	/**
	 * 播放
	 * @param pic
	 */
	public synchronized void play(String pic){
		if(!flag){ //生产者等待
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		//开始生产
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("生产了:"+pic);
		//生产完毕		
		this.pic =pic;
		//通知消费
		this.notify();
		//生产者停下
		this.flag =false;
	}
	
	public synchronized void watch(){
		if(flag){ //消费者等待
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		//开始消费
		try {
			Thread.sleep(200);
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		System.out.println("消费了"+pic);
		//消费完毕
		//通知生产
		this.notifyAll();
		//消费停止
		this.flag=true;
	}
}

package com.bjsxt.thread.pro;

public class App {
	public static void main(String[] args) {
		//共同的资源
		Movie m = new Movie();
		
		//多线程
		Player p = new Player(m);
		Watcher w = new Watcher(m);
		
		new Thread(p).start();		
		new Thread(w).start();
	}
}

在这里插入图片描述

/*测试管程法*/
package com.bjsxt.thread.pro;
public class TestProduce {
	public static void main(String[] args) {
		SyncStack sStack = new SyncStack();
		Shengchan sc = new Shengchan(sStack);
		Xiaofei xf = new Xiaofei(sStack);
		sc.start();
		xf.start();
	}
}

class Mantou {
	int id;
	Mantou(int id){
		this.id=id;
	}
}

class SyncStack{
	int index=0;
	Mantou[] ms = new Mantou[10];
	
	public synchronized void push(Mantou m){
		while(index==ms.length){
			try {
				this.wait(); 
				//wait后,线程会将持有的锁释放。sleep是即使睡着也持有互斥锁。
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notify(); //唤醒在当前对象等待池中等待的第一个线程。notifyAll叫醒所有在当前对象等待池中等待的所有线程。
		//如果不唤醒的话。以后这两个线程都会进入等待线程,没有人唤醒。
		ms[index]=m;
		index++;
	}
	public synchronized Mantou pop(){
		while(index==0){
			try {
				this.wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		this.notify();
		index--;
		return ms[index];
	}
}

class Shengchan extends Thread{
	SyncStack ss = null;
	
	public Shengchan(SyncStack ss) {
		this.ss=ss;
	}
	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			System.out.println("造馒头:"+i);
			Mantou m = new Mantou(i);
			ss.push(m);
		}
	}
}

class Xiaofei extends Thread{
	SyncStack ss = null;
	
	public Xiaofei(SyncStack ss) {
		this.ss=ss;
	}
	@Override
	public void run() {
		for (int i = 0; i < 20; i++) {
			Mantou m = ss.pop();
			System.out.println("吃馒头:"+i);
			
		}
	}
}

任务调度
线程同步与锁定_synchronized_单例模式_doubleChecking_生产者消费者模式_信号灯法_管程法_任务调度_多线程总结_第2张图片
线程同步与锁定_synchronized_单例模式_doubleChecking_生产者消费者模式_信号灯法_管程法_任务调度_多线程总结_第3张图片

了解
Timer()
schedule(TimerTask task, Date time)
schedule(TimerTask task, Date firstTime, long period)
自学 quartz

package com.bjsxt.thread.schedule;

import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
/**
    了解
  Timer() 
  schedule(TimerTask task, Date time) 
  schedule(TimerTask task, Date firstTime, long period) 
  自学 quartz
 * @author Administrator
 *
 */
public class TimeDemo01 {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Timer timer =new Timer();
		timer.schedule(new TimerTask(){

			@Override
			public void run() {
				System.out.println("so easy....");
			}}, new Date(System.currentTimeMillis()+1000), 200);
	}

}

总结:
一、创建线程 重点
1、继承 Thread
2、实现 Runnable
3、实现 Callable (了解)

二、线程的状态
线程同步与锁定_synchronized_单例模式_doubleChecking_生产者消费者模式_信号灯法_管程法_任务调度_多线程总结_第4张图片
1、
新生 -->start -->就绪 -->运行–>阻塞 -->终止
2、终止线程 (重点)
3、阻塞: join yield sleep
线程同步与锁定_synchronized_单例模式_doubleChecking_生产者消费者模式_信号灯法_管程法_任务调度_多线程总结_第5张图片

三、线程的信息
1、Thread.currentThread
2、获取名称 设置名称 设置优先级 判断状态

四、同步:对同一份资源
synchronized(引用类型变量|this|类.class){
}
修饰符 synchronized 方法的签名{
方法体
}
过多的同步可能造成死锁

五、生产者消费者模式

六、任务调度

后期 : juc quartz 自学。。。。

你可能感兴趣的:(JAVA基础)