java学习笔记(十七)

一、程序,进程和线程

程序:逻辑+数据,没有执行的指令序列和相关的数据的集合(如:qq.exe;磁盘上的可执行命令)

进程:正在执行的程序,进程占有资源(CPU,Memory,IO)

线程:是进程中并发运行的过程(共享进程资源)

同步:步调一致的顺序执行,如上公交车,一个一个上车

异步:步调不一致的同步执行,如:大家一起上卡车

线程:名词->类

1.Thread类中包含一个方法run()这个方法就是独立运行的过程(可用匿名内部类覆盖run())

2.Thread类中还包含方法start()用来启动独立运行的run()

创建一个线程:

1.覆盖Thread的run()方法,提供独立运行的过程(方式多种)

2.调用Thread实例的start()方法启动run()过程

实例:

public static void main(String[] args) {
		MyThread t=new MyThread();
		YourThread t2=new YourThread();
		t.setDaemon(true);
		t2.setPriority(Thread.MAX_PRIORITY-1);<span style="white-space:pre">				</span>//9
		t.start();							//启动run方法
		Thread.yield();<span style="white-space:pre">							</span>//当前线程让出处理器
		t2.start();
		System.out.println("Over");
	}
}
//通过继承来覆盖run()方法
class MyThread extends Thread{
	public void run(){
		for(int i=0;i<100;i++){
			System.out.println("我抽出皮筋做弹弓子,打你们家玻璃");
			if(i%2==0){
				Thread.yield();
			}
		}
	}
}
class YourThread extends Thread{
	public void run(){
		for(int i=0;i<100;i++){
			System.out.println("你干啥呢?");
		}
	}
}

二、线程

(一)线程状态:

1.new(新建)

2.Runnable

3.Running

4.Block

5.Died

(二)线程状态管理

1.Thread.yield()当前线程让出处理器(离开running),使当前线程进入Runnable等待

2.Thread.sleep(times)使当前线程从running放弃处理器进入Block状态,然后当休眠times这么多毫秒后,再返回到Runnable

3.如果其他线程打断当前线程的Block(sleep),就会发生InterruptedException

4.后台进程(守护线程,精灵线程)

java进程的结束,当所有前台线程都结束时,java进程结束。后台线程不管是否结束,都被停掉

t.setDaemon(true);//将t变成守护线程

实例:

public static void main(String[] args) {
		Thread t=new Thread(){
			public void run(){
				for(int i=0;i<5;i++){
					System.out.println("睡觉");
					try{
						Thread.sleep(1000);
					}catch(InterruptedException e){
						System.out.println("干啥呐");
						break;
					}
				}
			}
		};
		t.start();
		for(int i=0;i<5;i++){
			System.out.println("砸墙");
			try{
				Thread.sleep(500);
			}catch(InterruptedException e){
				e.printStackTrace();
			}
		}
		System.out.println("砸穿了");
		t.interrupt();//当前线程打断线程t的sleep
	}

(三)线程的优先级

默认有10优先级,优先级高的线程获得执行的机会多,机会的多少不能通过代码干预。默认的优先级是5

(四)两种方式创建线程

1.继承Thread类

a.继承Thread类,覆盖run()方法提供并发运行的机会

b.创建这个类的实例

c.使用start()方法启动线程

2.实现Runnable接口

a.实现Runnable接口,实现run()方法,提供并发运行的过程

b.创建这个类的实例,用这个实例作为Thread构造器参数创建Thread类

c.使用start()方法启动线程

3.使用内部类创建线程

可以使用Thread.currentThread()方法获得当前线程的引用

实例:

public static void main(String[] args) {//匿名内部类来开线程
		new Thread(){
			public void run(){
				for(int i=0;i<5;i++){
					System.out.println("HEY");
				}
			}
		}.start();
		
		new Thread(new Runnable(){
			public void run(){
				for(int i=0;i<5;i++){
					System.out.println("HEY");
				}
			}
		}).start();
	}
实例:

public class RunnableDemo {
	public static void main(String[] args) {
		Thread t1=new Thread(new Foo());
		Thread t2=new Thread(new Foo());
		Thread t3=new Thread(new Foo());
		t1.start();
		t2.start();
		t3.start();
	}
}
class Foo implements Runnable{
	public void run(){
		for(int i=0;i<5;i++){
			System.out.println("HEY");
		}
	}
}

(五)线程同步

1.多个线程并发读写同一个临界资源时会发生线程安全问题

2.可以使用同步代码块解决同步读写临界资源,解决并发安全问题

3.a.同步代码块

synchronized(this){}

b.同步监视器是一个任意对象实例,是一个多个线程之间的互斥的锁机制,多个线程要使用同一个“监视器”实现同步互斥

c.常见写法:

synchronized(this){}

d.如果方法的全部过程需要同步,可简单使用synchronized修饰方法

实例:

public class SyncDemo {
	int i=1;
	Object monitor=new Object();
	public synchronized int getNumber(){//public synchronized int getNumber=public int getNumber{synchronized(this)}
	//	synchronized (monitor){//加锁,同一把锁,也就是这个monitor要定义在前面,像我们这里写的那样,但显得比较不好,所以一般用this当锁
			if(i==20){
				throw new RuntimeException("Over");
			}
			try{
				Thread.sleep(10);
			}catch(InterruptedException e){
				e.printStackTrace();
			}
			return i++;
		//}
	}
	//两个线程并发
	public void go(){//非静态方法,不能讲下面的代码直接放到main里面,因为静态方法不能调非静态方法
		Thread t1=new MyThread();
		Thread t2=new MyThread();
		t1.start();
		t2.start();
		}
	public static void main(String[] args) {
		new SyncDemo().go();			
	}	
	class MyThread extends Thread{//使用内部类开线程
		public void run(){
			while(true){
				System.out.println(getNumber());
			}
		}
	}
}

java中同步的API:

1.StringBuffer是同步的 synchronized append()

  StringBuilder不是同步的 append()

2.Vector和HashTable 同步

  ArrayList和HashMap 不同步

3.Collection.synchronizedList()

  ArrayList list=new ArrayList()

  List syncList=Collection.synchronizedList(list);

(六)异步进程之间协作通信

1.同步写文件操作:从控制台读取一行,立即写到文件中

2.异步写文件操作,从控制台读取一行,放入到缓冲区,等到缓冲区满或者定时检查缓冲区,然后当缓冲区有内容的时候写入到文件中。

实例

<span style="white-space:pre">	</span>WriteThread w=new WriteThread();
	ReadThread r=new ReadThread();
	
	List<String> buf=new ArrayList<String>();
	class WriteThread extends Thread{
		public void run(){
			try{
				PrintWriter out=new PrintWriter(
						new FileWriter("unsyncio.txt",true));//追加方式打开
				while(true){
					if(buf.isEmpty()){
						try{
							Thread.sleep(5000);
						}catch(InterruptedException e){}
						continue;
					}
			//		out.println(buf);//这里最好写一个迭代
					for(String str:buf){
						out.println(buf);
					}
					System.out.println("Writing...");
					buf.clear();
					out.close();
				}
			}catch(IOException e){
				e.printStackTrace();
			}
		}
	}
	class ReadThread extends Thread{
		public void run(){
			BufferedReader console=
					new BufferedReader(
							new InputStreamReader(
									System.in));
			String str;
			try{
				while((str=console.readLine())!=null){
					buf.add(str);
			//		w.interrupt();
					if("exit".equalsIgnoreCase(str)){
						w.interrupt();
						break;
					}
				}
			}catch(IOException e){
				e.printStackTrace();
			}
		}
	}
	public void go(){
		w.setDaemon(true);
		w.start();
		r.start();
	}
	public static void main(String[] args) {
		new UnsyncIODemo().go();

	}

三、Timer计时器

底层是一个线程

实例:

public static void main(String[] args) {
		Timer t=new Timer();
		t.schedule(new TimerTask(){
			int i=10;
			public void run(){
				System.out.println("还有"+i--);
				if(i==0){
					t.cancel();
					System.out.println("我还会回来的");
				}
			}
		}, 1000,5000);

	}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值