Day11 JAVA复习

十一、线程

1.基本概念

1.程序:静态代码
2.进程:代码执行,动态执行过程,具有独立内存
3.线程:是进程的最小执行单位(main本身就是个线程),共享进程的资源

2. 线程

注意:线程的运行是不可预知的

2.1 创建线程的两种方式

1.extends Thread

public class Demo1 {
	//main方法主线程,可以管理其他线程
	public static void main(String[] args) {
		MyThread t=new MyThread();
		MyThread2 t2=new MyThread2();
		//启动线程start方法
		//t、t2的运行随机
		t.start();
		t2.start();
	}
}
class MyThread extends Thread{
	//线程方法run
		public void run(){
			for(int i=1;i<1000;i++){
				System.out.println("t1");
			}
		}
}
class MyThread2 extends Thread{
	//线程方法run
		public void run(){
			for(int i=1;i<1000;i++){
				System.err.println("t2");
			}
		}
}

2.implements Runnable接口,实现接口的这个类不是线程

public class Demo2 {
	public static void main(String[] args) {
		Runnable r=new Runnable(){
			@Override
			public void run() {
				for(int i=1;i<100000;i++){
					System.out.println("r1");
				}
			}
		};
		//就是不再调用thread类的run方法,替换成runnable接口中的run方法
		Thread t=new Thread(r);
		t.start();
		Thread t2=new Thread(()->{
			for(int i=1;i<100000;i++){
				System.err.println("r2");
			}
		});
		t2.start();
	}
}

2.2 线程常用的方法

注意:sleep()不会释放资源,wait()会释放资源

public class Demo3 {
	//主线程
	public static void main(String[] args) {
		/*Thread t = new Thread(){
			public void run(){*/
				//Thread.currentThread()获取正在运行的线程对象
				Thread th=Thread.currentThread();
				//Thread.currentThread().getName()获取线程的名称
				String str=Thread.currentThread().getName();
				//Thread.currentThread().getId()获取线程的唯一标识
				long id=Thread.currentThread().getId();
				//Thread.currentThread().isAlive()判断线程是否还活着
				boolean b=th.isAlive();
				System.out.println(th);
				System.out.println(str);
				System.out.println(id);
				System.out.println(b);
		/*	};
		};
		t.start();*/
	}
}
/*
 * sleep方法让线程休眠
 */
public class Demo4 {
	public static void main(String[] args) throws Exception {
		/*for(int i=1;i<=10;i++){
			System.out.println(i);
			//让线程休眠时间单位为ms   1000ms=1s
			//如果在休眠过程中被唤醒,会触发InterruptedException异常 
		    Thread.sleep(1000);
		}*/
		for(int i=0;i<=10;i++){
			int n=10-i;
			Thread.sleep(1000);
			System.out.println(n);
		}	
		System.out.println("过年了");
	}
}
/*
 * join方法
 * 等待一个线程执行结束
 */
public class Demo5 {
	public static void main(String[] args) {
		Thread t1=new Thread(){
			public void run(){
				for(int i=1;i<=10;i++){
				System.out.println("1");
				}
			}
		};
		Thread t2=new Thread(()->{
			for(int i=1;i<=10;i++){
				System.out.println("2");
				if(i==3){
					try {
						t1.join();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		},"线程2");
		t2.start();
		t1.start();
	}
}

小练习

public class test {
	public static void main(String[] args) {
		Thread t1=new Thread(){
			public void run(){
				System.out.println("开始下载图片");
				for(int i=0;i<=100;i++){
					System.out.println("下载"+i+"%");
					try {
						Thread.sleep(100);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
				System.out.println("下载完毕");
			}
		};
		Thread t2=new Thread(()->{
			System.out.println("显示图片");
			try {
				t1.join();
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			System.out.println("显示图片完成");
		},"线程2");
		t2.start();
		t1.start();
	}
}
/*
 * 守护线程
 * 线程可以分为:前台线程和后台线程(守护线程)
 * 默认情况下,创建的都是前台线程
 * 使用setDaemon(true),改变前台线程为后台线程
 * 两种线程在创建和使用上没有区别
 * 区别:如果前台线程结束,那么所有的后台线程也执行结束
 */
public class Demo6 {
	public static void main(String[] args) {
		Thread rose=new Thread(){
			public void run(){
				for(int i=1;i<=3;i++){
					System.out.println("我要跳船");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
					System.out.println("一起跳");
			}
		};
		Thread jack=new Thread(){
			public void run(){
				while(true){
					System.out.println("我不跳");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		};
		rose.start();
		//把线程设置为后台线程
		jack.setDaemon(true);
		jack.start();
	}
}

2.3 线程的生命周期

  • 新建状态:new Thread();
  • 就绪状态:start方法(接收调度)
  • 运行状态:run方法(线程体方法)
  • 阻塞状态(让出CPU资源):sleep(1000)、wait()、I/O
  • 死亡状态:运行完run方法的最后一条语句

2.4 线程调度

同一优先级:先到先服务
不同优先级:优先极高的先运行,然后优先级低的运行

2.5 优先级

系统默认:1、5、10,一般都是中等优先级
人为设置:(内存足够时优先级并没有太大影响)

	//设置线程优先级
		t1.setPriority(Thread.MIN_PRIORITY);
		t2.setPriority(Thread.NORM_PRIORITY);
		t3.setPriority(Thread.MAX_PRIORITY);

2.6线程的同步

  • 为什么实现同步:多个线程操作一个共享变量时,会使变量发生数据的不完整性(逻辑错误),需要实现线程同步
  • 实现线程同步的方案:把修改变量的方法或者块修饰为同步方法或者同步块 synchronized 关键字来修饰
public class Demo9 {
	static int tickets = 10;
	public static void main(String[] args) {
		Saler s1=new Saler();
		Saler s2=new Saler();
		s1.start();
		s2.start();
	}
}
class Saler extends Thread{
	public synchronized void run(){
		while(true){
				synchronized(Demo9.class){	
			if(Demo9.tickets==0){
				try {
					throw new Exception("没票了");
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}	
				break;
				}
		Demo9.tickets--;	
		System.out.println(Thread.currentThread().getName()+"窗口买了一张票,还剩"+Demo9.tickets+"张票");
				try {
				Thread .sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
				}
				}
		}
	}
public class Demo10 {
	/*public static void main(String[] args) {
		Shop s1=new Shop();
		Shop s2=new Shop();
		s1.start();
		s2.start();
	}
}
class Shop extends Thread{
	public void run(){
		System.out.println("挑衣服");
		try {
			Thread.sleep(500);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		synchronized(Shop.class){
		System.out.println("试衣服");
		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		}
		System.out.println("试完了");
	}*/
	
	public static void main(String[] args) {
		Shop shop = new Shop();
		Myth t1 = new Myth(shop);
		Myth t2 = new Myth(shop);
		t1.start();
		t2.start();
	}}
	class Myth extends Thread{
		Shop shop;
		public Myth(Shop shop){
			this.shop=shop;
		}
		public void run(){
			shop.method();
		}
	}
	class Shop {
		public void method(){
			System.out.println("挑衣服");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			synchronized(Shop.class){
			System.out.println("试衣服");
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			}
			System.out.println("试完了");
		}
	}

2.7 同步线程的通信

wait();//当前线程处于阻塞状态
notify()notifyAll()//唤醒等待的线程

public class Demo8 {
	public static void main(String[] args) {
		Bank b=new Bank();
		Thread t1=new Thread(()->{
			b.take(20);
		});
		Thread t2=new Thread(()->{
			b.take(50);
		});
		Thread t3=new Thread(()->{
			b.save(100);
		});
		t1.start();
		t2.start();
		t3.start();
	}
}
class Bank{
	int money=100;
	int a=0;
	public synchronized void take(int money){
		for(int i=1;i<=3;i++){
			
			if(this.money<50){
				//当》=50行动
				try {
					wait();
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}else{
				a=this.money;
				this.money-=money;
			System.out.println(Thread.currentThread().getName()+"     "+a+"-"+money+"="+this.money);
			}
			try {
				Thread.sleep(1000);
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
	public synchronized void save(int money){
		for(int i=1;i<=2;i++){
			int b=0;
			b=this.money;
			this.money+=money;
			System.out.println(Thread.currentThread().getName()+"     "+b+"+"+money+"="+this.money);
		}
		notifyAll();//唤醒wait的所有线程
	}
}

2.8 线程池

public class Demo11 {
	public static void main(String[] args) {
		//1.获取线程池
		ExecutorService threadPool=Executors.newFixedThreadPool(3);
		//2.添加线程到线程池
		for(int i=1;i<=6;i++){
			Thread t=new Thread(()->{
				System.out.println(Thread.currentThread().getName()+":开始执行");
				try {
					Thread.sleep(2000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+":执行完毕");
			});
			threadPool.execute(t);//添加线程到线程池
		}
		//3.关闭线程
		threadPool.shutdown();//不关闭正在执行的线程
		//threadPool.shutdownNow();//不管线程是否执行完毕,立即停止执行
		System.out.println("关闭线程!");
	}
}

2.9线程练习

//例题,用来看
public class Demo {
	final static Object obj =new Object();//锁
	static String name[]=new String[10];
	static String sex[]=new String[10];
	static int count=0;
	static final int SUM=5;
	public static void main(String args[]){
        Thread thread1=new read();
        Thread thread2=new write();
        thread1.start();
        thread2.start();
	}
	public static class write extends Thread{
		public void run() {
			Scanner sc = new Scanner(System.in); 
			while(count<SUM) {
				synchronized (obj) {
					if(name[count]!=null) {
						try {
							obj.wait();
							System.out.println("wirte thread wait over");
						}catch(InterruptedException e) {
								e.printStackTrace();
							}
					}
					System.out.println("write thread get obj lock");
					System.out.println("请输入第"+count+"个人的姓名:"); 
					name[count] = sc.nextLine(); 
					System.out.println("请输入性别:"); 
					sex[count] = sc.nextLine(); 
					System.out.println("写好了数据"+count);
					obj.notify();
					System.out.println("write thread notify read one ");
				}
			}
			sc.close();
			
		}
	}
	public static class read  extends Thread{
		public void run() {
			while(count<SUM) {
				synchronized (obj) {
					System.out.println("read thread get obj lock");
					try {
						if(name[count]==null)
						obj.wait();
						System.out.println("read thread don't wait");
					}catch(InterruptedException e) {
							e.printStackTrace();
						}
					try {
						System.out.println("姓名:"+name[count]+",性别:"+sex[count]);
	                    Thread.sleep(50);
	    				System.out.println("读好了数据"+count);
	    				count++;
	    				obj.notify();
	                } catch (InterruptedException e) {
	                    // TODO Auto-generated catch block
	                    e.printStackTrace();
	                }
				}
				System.out.println("read don't have obj lock");
				
			}
		}
	}
}
//12A  34B  --------5152Z
public class Test1 {
	public static void main(String[] args) {
		Object obj=new Object();
		new Thread(new Num(obj)).start();
		new Thread(new Zimu(obj)).start();
	}
}
class Num implements Runnable{
	private Object obj;
	public Num(Object obj){
		this.obj=obj;
	}
	@Override
	public void run() {
		synchronized(obj){
			for(int i=1;i<53;i++){
				if(i>1&&i%2!=0){
					System.out.println("  ");
				}
				System.out.print(i);
				obj.notify();//通知等的线程,但是要执行完当前代码块的代码
				if(i%2==0){
					try {
						obj.wait();//线程挂起,让出CPU资源
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
}
class Zimu implements Runnable{
	private Object obj;
	public Zimu(Object obj){
		this.obj=obj;
	}
	@Override
	public void run() {
		synchronized(obj){
			for(char i='A';i<='Z';i++){
					System.out.print(i);
				obj.notify();//通知等的线程,但是要执行完当前代码块的代码
				if(i<'Z'){
					try {
						obj.wait();//线程挂起,让出CPU资源
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
}
public class test1 {
	static final Object o=new Object();//锁,保证两个线程用同一锁进行资源的使用与释放的调度
	public static void main(String[] args) {
		Thread thread1=new Number();
        Thread thread2=new Zimu();
        thread1.start();
        thread2.start();
	}
public static class Number extends Thread{
		public void run(){
			for(int i=1;i<52;i=i+2){
				synchronized (o){
				int x=i+1;
					System.out.print(i+""+x);
					o.notifyAll();
					try {
						o.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
public static class Zimu extends Thread{
		public void run(){
			synchronized (o){
			for(char i='A';i<='Z';i++){
				if(i=='Z'){
					System.out.print(i);
					o.notify();
				}else{
					System.out.print(i);
					System.out.println("");
					o.notifyAll();
					try {
						o.wait();
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
				}
			}
		}
	}
}
/*
 *    0:1,2,3,4,5,
 *    1:6,7,8,9,10,
 *    2:11,12,13,14,15,
 *    0:16,17,18,19,20,
 *    1:21,22,23,24,25,
 */
public class Test2 {
	public static void main(String[] args) {
		Object obj=new Object();
		new Thread(new Number(obj,0)).start();
		new Thread(new Number(obj,1)).start();
		new Thread(new Number(obj,2)).start();
	}
}
class Number implements Runnable{
	Object obj;
	int id;
	static int num=1;
	public Number(Object obj,int id){
		this.obj=obj;
		this.id=id;
	}

	@Override
	public void run() {
		synchronized(obj){
			while(num<=75){
				if(num/5%3==id){
					System.out.print(id+": ");
					for(int i=1;i<=5;i++){
						System.out.print(num++ +",");
						try {
							Thread.sleep(500);
						} catch (InterruptedException e) {
							// TODO Auto-generated catch block
							e.printStackTrace();
						}
					}
					System.out.println();
					obj.notifyAll();
				}else{
					try {
						obj.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值