JAVA-day10-多线程2、IO初步

/*
生产者消费者
生产者负责生产,有生产任务
消费之负责消费,有消费任务

生产和消费可以同时进行

既然要同时进行,就得使用多线程

需要描述生产任务
描述消费任务

生产和消费的都是产品
还需要对产品进行描述

一个生产者线程,一个消费者线程,程序运行没问题
*/
//描述产品

class Product
{
	private String name;
	private int count;
    private boolean flag = false;

	//生产产品
	public synchronized void produce(String name)
	{
	   if(flag)
		   try{this.wait();}catch(InterruptedException e){e.printStackTrace();}
	   this.name = name+"...."+count;
	   count++;
	   System.out.println(Thread.currentThread().getName()+"生产了..."+this.name);
	   flag = true;
	   this.notify();
	}
   //消费产品
    public synchronized void consume()
	{
		if(!flag)
		   try{this.wait();}catch(InterruptedException e){e.printStackTrace();}
       System.out.println(Thread.currentThread().getName()+"....消费了..."+this.name);
	   flag = false;
	   this.notify();
    }
}

//描述生产任务

class Producer implements Runnable
{
	private Product product = null;

	public Producer(Product product)
	{
		this.product = product;
	}
	public void run()
	{
		while(true)
		{
			product.produce("笔记本");
		}
	}
}
//描述 消费任务

class Consumer implements Runnable
{
	private Product product = null;

	public Consumer(Product product)
	{
		this.product = product;
	}
	public void run()
	{
		while(true)
		{
			product.consume();
		}
	}
}

class Demo2 
{
	public static void main(String[] args) 
	{
		//创建产品对象

		Product pro = new Product();

		//创建生产任务对象
		Producer  producer = new Producer(pro);

		//创建消费任务对象
		Consumer  consumer = new Consumer(pro);

		//创建生产者线程

		Thread t0 = new Thread(producer);

		//创建消费者线程

		Thread t1 = new Thread(consumer);


		t0.start();
		t1.start();






	}
}




/*
生产者消费者
生产者负责生产,有生产任务
消费之负责消费,有消费任务

生产和消费可以同时进行

既然要同时进行,就得使用多线程

需要描述生产任务
描述消费任务

生产和消费的都是产品
还需要对产品进行描述

一个生产者线程,一个消费者线程,程序运行没问题
多个生产者线程,duoge消费者线程,程序运行出现了问题

出现了生产多次,消费一次,或者生产一次,消费多次的现象
出现问题的原因:一个线程被唤醒之后,没有去判断标记,直接执行
下边的代码

解决方式:  把if判断改成while判断,让每个被 唤醒的线程先去判断标记
而不是直接去生产后消费

该成while判断之后,又出现了死锁的问题

出现死锁的原因:因为notify()唤醒的是线程池中的任意一个线程,所以可能唤醒的是本方线程,导致所有线程等待

解决方式:还有一个notifyAll() 方法,唤醒的是线程池中的所有的线程,这样就能保证唤醒对方的线程了

          使用notifyAll()唤醒线程池中的所有线程,解决了问题,但是不需要被唤醒的也被唤醒了,程序性能降低
       
从jdk1.5解决了一次唤醒所有线程,性能低的问题

*/
//描述产品

class Product
{
	private String name;
	private int count;
    private boolean flag = false;

	//生产产品
	public synchronized void produce(String name)
	{
	   while(flag)
		{
		   try{
		         this.wait();//t0,t1

			   }catch(InterruptedException e)
				    {e.printStackTrace();}
		}
	   this.name = name+"...."+count;
	   count++;
	   System.out.println(Thread.currentThread().getName()+"生产了..."+this.name);
	   flag = true;
	   //this.notify();
	   notifyAll();
	}
   //消费产品
    public synchronized void consume()
	{
		while(!flag)
		{
		   try{this.wait();}
		   catch(InterruptedException e)
			   {e.printStackTrace();}
		}
       System.out.println(Thread.currentThread().getName()+"....消费了..."+this.name);
	   flag = false;
	   //this.notify();
	   notifyAll();//唤醒所有等待线程
    }
}

//描述生产任务

class Producer implements Runnable
{
	private Product product = null;

	public Producer(Product product)
	{
		this.product = product;
	}
	public void run()
	{
		while(true)
		{
			product.produce("笔记本");
		}
	}
}
//描述 消费任务

class Consumer implements Runnable
{
	private Product product = null;

	public Consumer(Product product)
	{
		this.product = product;
	}
	public void run()
	{
		while(true)
		{
			product.consume();
		}
	}
}

class Demo3
{
	public static void main(String[] args) 
	{
		//创建产品对象

		Product pro = new Product();

		//创建生产任务对象
		Producer  producer = new Producer(pro);

		//创建消费任务对象
		Consumer  consumer = new Consumer(pro);

		//创建生产者线程

		Thread t0 = new Thread(producer);
		Thread t1 = new Thread(producer);

		//创建消费者线程

		Thread t2 = new Thread(consumer);
		Thread t3 = new Thread(consumer);



		t0.start();
		t1.start();
		t2.start();
		t3.start();






	}
}


/*
jdk1.5实现多线程的方式:

jdk1.5之前使用的是同步代码块,对锁的操作是隐式的
synchronized(对象)//获取锁
{

}//释放锁

jdk1.5开始对锁的操作就是显示的了:专门为锁定义了描述的接口,Lock
1:获取锁  lock()
2:释放锁  unlock()

Lock可以替代同步代码块
1:创建一把锁,使用Lock的子类ReentranLock
2:把需要同步的代码放在lock()和unlock()之间

使用Lock,把锁替换后,出现了IllegalMonitorStateException,无效的监视器状态异常
同步代码块没有了,而wait(),notify(),notifyAll()还必须用在同步代码块中,
所以出现异常

解决方式就得看新的jdk1.5的api,发现有一个 和Lock相关的Condition接口,该接口中定义了
await(),signal(),signalAll()方法,替代了之前的wait(),notify(),notifyAll()三个方法,
因为单独对这三个方法进行了描述,所以更加的面向对象

使用Lock的newCondition方法,得到一个和锁绑定的Condition对象,从而实现唤醒等待的互斥


*/

//描述产品
import java.util.concurrent.locks.*;
class Product
{
	private String name;
	private int count;
    private boolean flag = false;

	// 创建一把锁
	Lock lock = new ReentrantLock();

    //创建和锁绑定的Condition对象
	Condition con = lock.newCondition();

	//生产产品
	public  void produce(String name)
	{
	   lock.lock();//获取锁
	   try{
		   while(flag)
			{
			   try{
					 con.await();

				   }catch(InterruptedException e)
						{e.printStackTrace();}
			}
		   this.name = name+"...."+count;
		   count++;
		   System.out.println(Thread.currentThread().getName()+"生产了..."+this.name);
		   flag = true;
		   //this.notify();
		   con.signalAll();
	   }
       finally{
			lock.unlock();//释放锁
	   }
	}
   //消费产品
    public  void consume()
	{   lock.lock();
	    try{
			while(!flag)
			{
			   try{con.await();}
			   catch(InterruptedException e)
				   {e.printStackTrace();}
			}
		   System.out.println(Thread.currentThread().getName()+"....消费了..."+this.name);
		   flag = false;
		   //this.notify();
		   con.signalAll();//唤醒所有等待线程
	    }finally{
			 lock.unlock();
		}
    }
}

//描述生产任务

class Producer implements Runnable
{
	private Product product = null;

	public Producer(Product product)
	{
		this.product = product;
	}
	public void run()
	{
		while(true)
		{
			product.produce("笔记本");
		}
	}
}
//描述 消费任务

class Consumer implements Runnable
{
	private Product product = null;

	public Consumer(Product product)
	{
		this.product = product;
	}
	public void run()
	{
		while(true)
		{
			product.consume();
		}
	}
}

class Demo4
{
	public static void main(String[] args) 
	{
		//创建产品对象

		Product pro = new Product();

		//创建生产任务对象
		Producer  producer = new Producer(pro);

		//创建消费任务对象
		Consumer  consumer = new Consumer(pro);

		//创建生产者线程

		Thread t0 = new Thread(producer);
		Thread t1 = new Thread(producer);

		//创建消费者线程

		Thread t2 = new Thread(consumer);
		Thread t3 = new Thread(consumer);



		t0.start();
		t1.start();
		t2.start();
		t3.start();






	}
}


/*
使用jdk1.5的Lock和Conditiong,解决多生产多消费,一次唤醒所有线程性能低的问题

一次只唤醒一个对方线程
*/

//描述产品
import java.util.concurrent.locks.*;
class Product
{
	private String name;
	private int count;
    private boolean flag = false;

	// 创建一把锁
	Lock lock = new ReentrantLock();

    //创建和锁绑定的Condition对象,负责生产线程的等待和唤醒
	Condition pro = lock.newCondition();

	 //创建和锁绑定的Condition对象,负责消费线程的等待和唤醒
	Condition con = lock.newCondition();

	//生产产品
	public  void produce(String name)
	{
	   lock.lock();//获取锁
	   try{
		   while(flag)
			{
			   try{	pro.await();}catch(InterruptedException e){e.printStackTrace();}
			}
		   this.name = name+"...."+count;
		   count++;
		   System.out.println(Thread.currentThread().getName()+"生产了..."+this.name);
		   flag = true;
		   //this.notify();
		   con.signal();
	   }
       finally{
			lock.unlock();//释放锁
	   }
	}
   //消费产品
    public  void consume()
	{   lock.lock();
	    try{
			while(!flag)
			{
			   try{con.await();}
			   catch(InterruptedException e)
				   {e.printStackTrace();}
			}
		   System.out.println(Thread.currentThread().getName()+"....消费了..."+this.name);
		   flag = false;
		   //this.notify();
		   pro.signal();//唤醒所有等待线程
	    }finally{
			 lock.unlock();
		}
    }
}

//描述生产任务

class Producer implements Runnable
{
	private Product product = null;

	public Producer(Product product)
	{
		this.product = product;
	}
	public void run()
	{
		while(true)
		{
			product.produce("笔记本");
		}
	}
}
//描述 消费任务

class Consumer implements Runnable
{
	private Product product = null;

	public Consumer(Product product)
	{
		this.product = product;
	}
	public void run()
	{
		while(true)
		{
			product.consume();
		}
	}
}

class Demo5
{
	public static void main(String[] args) 
	{
		//创建产品对象

		Product pro = new Product();

		//创建生产任务对象
		Producer  producer = new Producer(pro);

		//创建消费任务对象
		Consumer  consumer = new Consumer(pro);

		//创建生产者线程

		Thread t0 = new Thread(producer);
		Thread t1 = new Thread(producer);

		//创建消费者线程

		Thread t2 = new Thread(consumer);
		Thread t3 = new Thread(consumer);



		t0.start();
		t1.start();
		t2.start();
		t3.start();






	}
}


/*
实现可以同时生产多个产品,可以同时消费多个产品


*/
import java.util.concurrent.locks.*;
//描述产品
class Clothes
{
	//衣服名称
	private String name;
	// 衣服价格
	private double price;

	//定义一把锁
	private final Lock lock = new ReentrantLock();

	//定义和锁绑定的Condition对象
	private final Condition pro = lock.newCondition();

	//定义和锁绑定的Condition对象
	private final Condition con = lock.newCondition();

    //定义用来存储商品的容器
	private Clothes[]  arr= new Clothes[100];

	//propointer生产者使用的下标,conpointer消费者使用的下标,count商品数量
	private int propointer,conpointer,count;

	public Clothes(){}
	public Clothes(String name,double price){
		this.name = name;
		this.price = price;
	}
	//生产衣服
    public void produce()
	{
		lock.lock();
		try
		{   //当商品的数量和容器的容量相同时,生产者等待
			while(arr.length==count)
			{
				try{pro.await();}catch(InterruptedException e){e.printStackTrace();}
			}
			//生产产品,并放入容器中
            arr[propointer]  = new Clothes("羽绒服",399);
			System.out.println(Thread.currentThread().getName()+"生产了..."+arr[propointer]+"=="+count);
            //如果下标加1后和容器长度相同了,下标重新赋值为0
			if(++propointer==arr.length)
				propointer = 0;
			//数量加1
			count++;
            //唤醒对方一个线程
			con.signal();
		}
		finally
		{
			lock.unlock();
		}
	}
    //消费衣服
    public void consume()
	{
		lock.lock();
		try
		{
			当商品的数量为0时,消费者等待
			while(count==0)
			{
				try{con.await();}catch(InterruptedException e){e.printStackTrace();}
			}
			//从容器中取出一个商品
			Clothes yifu = arr[conpointer];
			System.out.println(Thread.currentThread().getName()+"....消费了..."+yifu+"===="+count);
			//如果下标加1后和容器长度相同了,下标重新赋值为0
			if(++conpointer==arr.length)
				conpointer = 0;
            //数量减1
			--count;
			//唤醒对方一个线程
			pro.signal();

		}
		finally
		{
			lock.unlock();
		}
	}

	public String toString()
	{
		return name+","+price;
	}
}
//生产任务
class Producer implements Runnable
{
	private Clothes clo;
	public Producer(Clothes clo)
	{
		this.clo = clo;
	}
	public void run()
	{
	   while(true)
		{
			clo.produce();
	    }
	}
}
//消费任务
class Consumer implements Runnable
{
	private Clothes clo;
	public Consumer(Clothes clo)
	{
		this.clo = clo;
	}
	public void run()
	{
		while(true)
		{
			clo.consume();
		}
	
	}
}

class Demo6 
{
	public static void main(String[] args) 
	{
		Clothes clo = new Clothes();

		
		//创建生产任务对象
		Producer  producer = new Producer(clo);

		//创建消费任务对象
		Consumer  consumer = new Consumer(clo);

		//创建生产者线程

		Thread t0 = new Thread(producer);
		Thread t1 = new Thread(producer);

		//创建消费者线程

		Thread t2 = new Thread(consumer);
		Thread t3 = new Thread(consumer);



		t0.start();
		t1.start();
		t2.start();
		t3.start();


	}
}

//线程的停止:stop方法已经过时,那么就只能是线程的任务代码执行完才能停止线程
//但是通常任务代码中都会有循环,所以只要让循环停止,线程就能停止

//interrupt:清除线程的等待或睡眠状态,join状态
class Test implements Runnable
{
   boolean flag = true;
   public synchronized void run()
	{
	   while(flag)
		{
		      try{wait();}
			  catch(InterruptedException e )
				{
			       System.out.println("异常啦");
				   flag = false;
			    }
			System.out.println(Thread.currentThread().getName()+"Hello World");
		}
    }
   public void changeFlag()
	{
	  this.flag = false;
    }
}
class  Demo7
{
	public static void main(String[] args) 
	{
		Test t = new Test();

		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);

		t1.start();
		t2.start();

		try{Thread.sleep(10);}catch(InterruptedException e){e.printStackTrace();}

		int i=1;
		while(true)
		{
			if(++i==500)
			{ 
				//t.changeFlag();
				t1.interrupt();
				t2.interrupt();
			    break;

			}
		}
	}
}

//守护线程:看成是后台线程,依赖于前台线程
class Test implements Runnable
{
   boolean flag = true;
   public synchronized void run()
	{
	   while(flag)
		{
		      try{
				  wait();
				}
			  catch(InterruptedException e )
				{
			       System.out.println("异常啦");
				   flag = false;
			    }
			System.out.println(Thread.currentThread().getName()+"Hello World");
		}
    }
   public void changeFlag()
	{
	  this.flag = false;
    }
}
class  Demo8
{
	public static void main(String[] args) 
	{
		Test t = new Test();

		Thread t1 = new Thread(t);
		Thread t2 = new Thread(t);
        t2.setDaemon(true);//把t2设置为守护线程,当前台线程全部执行完,守护线程即使没执行完任务代码也会结束 
		t1.start();
		t2.start();

		try{Thread.sleep(10);}catch(InterruptedException e){e.printStackTrace();}

		int i=1;
		while(true)
		{
			if(++i==500)
			{ 
				//t.changeFlag();
				t1.interrupt();//强制中断
				//t2.interrupt();
			    break;

			}
		}
	}
}




//join:让线程加入运行
class Test implements Runnable
{
   public void run()
	{
		for(int i=1;i<=10;i++)
		{
			System.out.println(Thread.currentThread().getName()+"..."+i);
		}
    }
}
class  Demo9
{
	public static void main(String[] args)throws InterruptedException 
	{
		Test t = new Test();
		
		Thread t1 = new  Thread(t);
		Thread t2 = new  Thread(t);

		t1.start();

		//t1.join();//因为这是只有主线程和t1线程,所以主线程会等t1线程全部执行完,才和t2线程交替执行

		t2.start();

		t1.join();//因为有t1,t2,主线程三个线程,所以t1和t2交替执行,主线程会等t1线程全部执行完,再和t2交替执行
        
		for(int i=1;i<=10;i++)
		{
			System.out.println(Thread.currentThread().getName()+"..."+i);
		}

	}
}

//线程池:
import java.util.concurrent.*;
class  Demo10
{
	public static void main(String[] args) 
	{
		//创建只有一个线程的线程池对象,执行完一个任务才能去执行下一个任务,任务是按照被提交的顺序执行的
		//ExecutorService   es = Executors.newSingleThreadExecutor();

//创建固定数量线程的线程池对象--任务数量没有超过线程数量,任务会被同时执行,超过的任务会等线程池中一个执行完任务的已存在线程来执行
		//ExecutorService   es = Executors.newFixedThreadPool(2); 

		//创建一个缓存的线程池对象--会自身创建一定数量的线程,如果这个线程数超过了任务数量,会自动回收空闲的线程,当有新增加线程时
		//会智能的增加线程
        //ExecutorService   es = Executors.newCachedThreadPool();

        //创建一个数量无限制的线程池对象
		ExecutorService   es = Executors.newScheduledThreadPool(3);




		//创建任务对象
		MyTask  mt1 = new MyTask();
        MyTask  mt2 = new MyTask();
		MyTask  mt3 = new MyTask();
        MyTask  mt4 = new MyTask();
		MyTask  mt5 = new MyTask();
		//让线程池中的线程去执行任务 
		es.execute(mt1);
		es.execute(mt2);
		es.execute(mt3);
		es.execute(mt4);
		es.execute(mt5);
		
		
	}
}





class MyTask implements Runnable
{
	public void run()
	{
		try
		{
			Thread.sleep(10);
		}
		catch (InterruptedException e)
		{
			e.printStackTrace();
		}
	   for(int i=1;i<=10;i++)
		{
	       System.out.println(Thread.currentThread().getName()+"---->"+i);
	    }
	}
}

//什么时候用多线程?相同的任务需要被同时执行,或者不同的任务被同时执行
class  Demo11
{
	public static void main(String[] args) 
	{
		//使用匿名内部类创建线程

		new Thread(){
		
		  public void run()
			{
		       System.out.println("haha");
		   }
		}.start();


		new Thread(new Runnable(){
		
		   public void run()
			{
		       System.out.println("haha");
		    }
		}).start();



		Runnable r = new Runnable(){
			public void run()
			{
		       System.out.println("haha");
		   }
		};
		new Thread(r).start();
	}
}

class MyThread extends Thread{
	public void run()
	{
		try {
			Thread.currentThread().sleep(3000);
		} catch (InterruptedException e) {
		}
		System.out.println("MyThread running");
	}
}
public class ThreadTest{

	public static void main(String argv[])
		{
			MyThread t = new MyThread();
			t.run();
			t.start();
			System.out.println("Thread Test");
	    }
}
/*
MyThread t = new MyThread();创建了一个线程对象,t.run()是普通的方法调用,执行run()方法中的代码,
因为当前线程只有主线程,所以是主线程先睡3秒,在主线程睡得期间程序不动了,睡够3秒后打印"MyThread running"
接下来执行 t.start()
接下来的执行有两种可能:
第一种可能:主线程仍然持有cpu,打印"Thread Test",主线程结束,这是子线程得到cpu,去执行run方法,
子线程先睡3秒,然后打印"MyThread running"
第二种可能:子线程得到cpu,执行run方法,子线程先睡3秒,睡的期间主线程得到了cpu,主线程打印"Thread Test"
然后子线程睡够了,打印"MyThread running"


*/



/*
IO流是用来处理设备之间的数据传输

IO流按照流向分为:输入流,输出流

按照流操作的数据分为:

字节流:可以操作任何类型的数据,包括文件,图片,视频,音频

Ascii   ISO8859-1  gb2312  gbk  utf-8
字符流:专门用来操作文本文件的,在字节流的基础上,融入了字符编码
所以说字符流是基于字节流的,就是为了方便操作文本文件


字节流:
输入流:InputStream
输出流: OutputStream

字符流:
输入流:Reader
输出流: Writer

我们最常 操作的设备是硬盘
所以我们以文件为例来讲输入输出

先使用字符流




*/
import java.io.*;
class Demo13 
{
	public static void main(String[] args) throws IOException
	{
		//往文本文件中写入数据
		//因为是文本文件,所以使用字符流,又因为是写入数据,所以使用Writer,又因为是文件,所以应该使用操作文件的字符输出流


		//创建文件输出流对象并和文件相关联
        //如果这个文件不存在,会自动创建,否则会覆盖
		FileWriter fw = new FileWriter("temp.txt");

		//通过文件输出流对象把数据写入到文件
        //数据写入到输出流对象内部的缓冲区了,这个缓冲区是一个字节缓冲区,目的是先查编码表,把查表结果写入到文件
        fw.write("abc");

       //把缓冲区中的数据刷到文件
	   //fw.flush();

	  // fw.write("ccc");//可以继续写入数据

       //关闭流
	   fw.close();//关闭流的同时,会刷新流

	   //fw.write();//流已经关闭,所以不能再写入数据

	}
}

import java.io.*;
class  Demo14
{
	public static void main(String[] args) 
	{
		FileWriter fw = null;
		try
		{
			fw = new FileWriter("temp.txt");//如果系统找不到指定的路径,该输出流对象就会创建失败
			fw.write("abcde");
		}
		catch (IOException e)
		{
			e.printStackTrace();
		}
		finally
		{
			try
			{
				if(fw!=null)
					fw.close();
			}
			catch (IOException e)
			{
				e.printStackTrace();
			}
			
		}
		
	}
}

//文件的续写
import java.io.*;
class Demo15 
{
	public static void main(String[] args)throws IOException 
	{
		final String LINESEPARATOR = System.getProperty("line.separator");

		FileWriter fw = new FileWriter("temp.txt",true);

		fw.write("de");

		fw.write(LINESEPARATOR);

		fw.write("fg");

		fw.close();
	}
}

import java.io.*;
class Demo16 
{
	public static void main(String[] args) throws IOException
	{
		//读取一个文本文件  因为是一个文本文件,所以使用字符流,又因为是读,所以使用Reader,又因为是读文件,所以使用FileReader

		//创建文件读取流对象和文件相关联

		FileReader fr = new FileReader("temp.txt");
		int num = 0;

		while((num = fr.read())!=-1)
		{
			System.out.print((char)num);
		}

		fr.close();

		//读取文件
		/*
		int num = fr.read();
		System.out.println((char)num);
		 num = fr.read();
		System.out.println((char)num);
		 num = fr.read();
		System.out.println((char)num);
		 num = fr.read();
		System.out.println((char)num);
	     num = fr.read();
		System.out.println((char)num);

		  num = fr.read();
		System.out.println(num);//-1

		*/
	}
}

import java.io.*;
class Demo17 
{
	public static void main(String[] args)throws IOException 
	{
		FileReader fr = new FileReader("temp.txt");//abcde

		char[] arr = new char[1024];
        
		int num =0;

		while((num= fr.read(arr))!=-1)
		{
			System.out.print(new String(arr,0,num));
		}

		fr.close();

		/*
		int num = fr.read(arr);
		System.out.print(new String(arr,0,2));

		num = fr.read(arr);
		System.out.print(new String(arr,0,2));

		num = fr.read(arr);
		System.out.print(new String(arr,0,1));

		num = fr.read(arr);
		System.out.print(num);
		*/
	}
}

import java.io.*;
class Demo19 
{
	public static void main(String[] args) 
    {
		FileReader fr = null;
		FileWriter fw = null;
		try
		{
			fr = new FileReader("Demo10.java");//该文件必须事先存在
		    fw = new FileWriter("Demo10_copy.java");

			char[] arr = new char[1024];
			int num = 0;
			while((num = fr.read(arr))!=-1)
			{
				fw.write(arr,0,num);
				fw.flush();
			}
		}
		catch (IOException e)
		{
			throw new RuntimeException("文件读写失败");
		}
		finally
		{
			if(fr!=null)
				try
				{
					fr.close();
				}
				catch (IOException e)
				{
					throw new RuntimeException("文件读取流关闭失败");
				}
			if(fw!=null)
				try
				{
					fw.close();
				}
				catch (IOException e)
				{
					throw new RuntimeException("文件写入流关闭失败");
				}
		}
		
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值