JAVA笔记九(35-38 内部类、匿名内部类以及java的线程)

三十五、内部类和匿名内部类

1.什么是内部类

class A{
	class B{
	}
}

编译后产生两个文件:A.class  和A$B.class

2.内部类的使用方法

class A{
	int i;
	
	class B{  //内部类可以随意使用外部类的成员变量和成员函数。
	int j;	  //每一个内部对象都对应一个外部对象
	
	int funB(){
		int result = i + j;	//A.this.i + j
		return result;
	}
	}
}

class test{
	public static void main(String[] args){
	A a = new A();
	
	//A.B b = new A().new B();   生成内部对象的代码。
	A.B b = a.new B();
	
	a.i = 3;
	b.j = 1;
	int result = b.funB();
		System.out.println(result);
	
	}
}

3.匿名内部类的使用方法

一个接口A,一个类B,B中有一个函数fun调用A的对象作为参数时,调用fun的过程:

1)定义接口A

interface A{
	public void dosomething();
}
2)定义B

class B{
	public void fun(A a){
		System.out.println("method fun of class B!");
		a.dosomething();
	}
}
3)定义A的实现类

class AImpl implements A{
	public void dosomething(){
		System.out.println("dosomething!");
	}
}
4)生成AImpl的对象,向上转型成A的对象;生成B的对象;调用fun函数。

class Test{
	public static void main(String[] args){
		A a = new AImpl();  
		B b = new B();
		b.fun(a);
		//不使用匿名内部类,需要定义一个A的实现类AImpl,然后实例化AIpl,并向上转型为A的对象。
		//使用匿名内部类,可以去掉定义A的实现类的步骤。直接生成一个没有名字的A实现类的对象作为fun函数的参数。
		/*B b = new B();
		*b.fun(new A(){       匿名实现类直接在大括号里复写接口里的函数。
		*	public void dosomething(){
		*		System.out.println("anonymous inner classes");
		*	}
		*});
		*/
	}
}

匿名内部类一般情况下都是写在参数里面的。

总结:

内部类就是一个类定义在另外一个类的内部,内部类可以随意使用外部类的成员变量和成员函数。生成内部类的对象的方法是:A.B b = new A().new B();

匿名内部类就是new一个接口,后面紧跟着一个类来实现这个接口,只不过这个类没有名字。

三十六、java当中的线程(一)

1.进程和线程

多进程:在操作系统中能(同时)运行多个任务(程序)。

多线程:在同一应用程序中有多个顺序流(同时)执行。线程是进程当中一个程序执行流程。

2.多线程程序运行模式


线程的生命周期:

线程是一个对象

3.定义线程的方法

创建线程的方法一:

定义一个线程类,它继承Thread并重写其中的方法run()。方法run()称为线程体;由于java只支持单继承,用这种方法定义的类不能再继承其他类。

class FristThread extends Thread{
	public void run(){
		for(int i = 0; i < 100;i++){
			System.out.println("FristThread  ——>>"+i);
		}
	}
}
class Test{
	public static void main(String[] args){
		//生成一个线程类的对象
		FristThread ft = new FristThread();
		//启动线程
		ft.start();
		
		//ft.run(); 这不是启动线程的代码,不要这样写。它不会启动线程,而是直接在主线程里直接先执行完run里面的代码。
		
		for(int j = 0;j< 120;j++){
			System.out.println("main ——>>"+j);
		}
	}
}
运行结果:

多线程程序执行的特点就是:没谱!哪个线程什么时候执行,取决于哪个线程抢到了CPU。所有每次运行的结果都不一样。

总结:

所谓线程,就是进程中的进一步分支,如果一个应用程序中有多个线程的话,那么这些线程会来回切换着运行。

三十七、java中的线程(二)

1.实现线程的第二种方法(用得更多)。

创建线程的方法二:

提供一个实现接口Runnable的类做为线程的目标对象,在初始化一个Thread类或者Thread子类的线程对象时,把目标对象传递给这个线程实例,由该目标对象提供线程体。

线程和线程体进行了分离。

class RunnableImpl implements Runnable{
	public void run(){
		for(int i = 0; i < 100; i++){
			System.out.println("Runnable ——>"+i);
		}
	}
}

class Test{
	public static void main(String[] args){
		// 生成一个Runnable接口实现类的对象
		RunnableImpl ri = new RunnableImpl();
		//生成一个Thread对象,并将Runnable接口实现类的对象作为参数传递给该Thread对象。
		Thread t = new Thread(ri);
		//通知Thread对象,执行start方法
		t.start();
	}
}

方法一和方法二都对run这个方法进行了复写,区别在于,一个是直接继承Thread;一个是实现了Runnable这个接口,这样避免了该线程类不能继承其他类的情况。

在实际开发过程中,继承能不用就不用,因为java中只支持单继承。

2.控制线程的常见函数。

中断线程

—Tread.sleep()     //后面要有一个参数,为毫秒数。线程体中执行了此段代码,当前线程就进入休眠状态,休眠时间到了之后,线程进入就绪状态

—Tread.yield()      //线程体重执行了此段代码,当前线程会让出CPU,但是仍保持就绪状态,跟其他线程抢CPU。


class RunnableImpl implements Runnable{
	public void run(){
		for(int i = 0; i < 100; i++){
			System.out.println("Runnable ——>"+i);
			try{
				if(i == 50){
					Thread.sleep(4000); //会产生中断,所以要用try。
				}
			}
			catch(Exception e){
				System.out.println(e);
			}
		}
	}
}

设置线程的优先级

—getPriority()

—setPriority()

class Test{
	public static void main(String[] args){
		RunnableImpl ri = new RunnableImpl();
		Thread t = new Thread(ri);
		
		//线程的优先级最大是10,最小是1,可以使用Thread所提供的静态常量或者1-10的整数来设置线程的优先级,
		//数字越大,线程执行的概率越高。
		// t.setPriority(Thread.MAX_PRIORITY);  //设置最大优先级
		t.setPriority(Thread.MIN_PRIORITY);		//设置最小优先级
		System.out.println(t.getPriority()); //获取优先级,并打印出来
		
		t.start();
		
	}
}

三十八、java当中的线程(三)

1.多线程数据安全(本讲主要讲保证数据的完整性)

多线程共用一份资源时,要么给每个线程复制一份数据,要么使用同步代码块。

2.同步线程的方法

使用同步锁 synchronized(this){代码},保证多线程共用数据时的数据安全。

class MyThread implements Runnable{
	int i = 100;
	public void run(){
		while(true){
			synchronized(this){ //同步锁,没有拿到这个锁时,线程等待。
				System.out.println(Thread.currentThread().getName()+i);
				i--;
				Thread.yield();
				if(i < 0){
					break;
				}
			}
		}
	}
}

class Test{
	public static void main(String[] args){
		MyThread mt = new MyThread();
		
		//生成两个Thread对象,但是这两个Thread对象公用同一个线程体
		Thread t1 =new Thread(mt);
		Thread t2 =new Thread(mt);
		
		//每一个线程都有名字,可以通过Thread对象的setName()方法设置线程名字,也可以使用getName()方法获取线程对象的名字;
		t1.setName("thread1   ");
		t2.setName("thread2   ");
		
		//分别启动两个线程
		t1.start();
		t2.start();
	
	}
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值