同步:并发 多个线程访问同一份资源 确保资源安全 -->线程安全
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("一手给货");
}
}
信号灯法
一、 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);
}
}
}
了解
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 (了解)
二、线程的状态
1、
新生 -->start -->就绪 -->运行–>阻塞 -->终止
2、终止线程 (重点)
3、阻塞: join yield sleep
三、线程的信息
1、Thread.currentThread
2、获取名称 设置名称 设置优先级 判断状态
四、同步:对同一份资源
synchronized(引用类型变量|this|类.class){
}
修饰符 synchronized 方法的签名{
方法体
}
过多的同步可能造成死锁
五、生产者消费者模式
六、任务调度
后期 : juc quartz 自学。。。。