java复习笔记day13

1.Java多线程

1.1基本概念:
程序:是为了完成特定任务、用某种语言编写的一组指令的集合。即指一段静态的代码,静态对象。
进程:是程序的一次执行过程,或是正在运行的一个程序。动态过程:有它自身的产生、存在和消亡的过程。
线程:进程可进一步细化为线程,是一个程序内部的一条执行路径。
若一个程序可以同一时间执行多个线程,就是支持多线程的。
1.2多线程好处:
提高应用程序的响应,对图形化界面更有意义,可增强用户体验。
提高计算机系统CPU的利用率。
改善程序结构,将既长又复杂的进程分为多个线程,独立运行,利于理解和修改。
1.3何时需要多线程:
程序需要同时执行两个或多个任务。
程序需要实现一些需要等待的任务时,如用户输入、文件读写操作、网络操作、搜索等。
需要一些后台运行的程序时。
1.4创建多线程的四种方式:
1.继承Thread类
2.实现Runnable接口
3.实现Callable接口
4.使用线程池

2.创建多线程的方式之一:继承Thread

start():启动线程,调用当前线程的run()
不能用调用 对象.run()的方式来启动线程。
一个线程只能启动一次。
如果需要创建多个线程,需要先创建多个对象,用不同的对象来启动线程。

package threadTest;

public class SubThread extends Thread{
//  1.创建主线程。
	public static void main(String[] args) {
//		3.实例化Thread类的子类
		SubThread s1 = new SubThread();
//		4.调用对象的start()
		s1.start();
		System.out.println("hello");
		for(int i = 1 ;i <= 1000 ;i++ )
			if(i%2 == 0)
				System.out.println(i + "----------");
	}
//	2.重写Thread类中的run(),将此线程要执行的操作,声明在run()的方法体中。
	@Override
	public void run(){
		for(int i = 1 ;i <= 1000 ;i++ )
			if(i%2 == 0)
				System.out.println(i);
	}
}

package threadTest;
/**
 * 创建两个分线程,一个线程实现100以内的偶数的遍历,另一个线程实现100以内的基数遍历
 */
public class ThreadExer {
	public static void main(String[] args) {
		MyThread1 m1 = new MyThread1();
		MyThread2 m2 = new MyThread2();
		m1.start();
		m2.start();
		//创建Thread类的匿名子类的匿名对象。
		new Thread(){
			public void run(){
				for(int i = 1 ;i <= 100;i++)
					if(i%2==0)
						System.out.println(Thread.currentThread().getName()+"====:"+i);
			}
		}.start();
	}
	
}
class MyThread1 extends Thread{
	@Override
	public void run(){
		for(int i = 1 ;i <= 100;i++)
			if(i%2==0)
				System.out.println(Thread.currentThread().getName()+"----:"+i);
	}
}
class MyThread2 extends Thread{
	@Override
	public void run(){
		for(int i = 1 ;i <= 100;i++)
			if(i%2!=0)
				System.out.println(Thread.currentThread().getName()+":"+i);
	}
}

3.使用同步的方式和使用Lock的方式有什么异同?
同,都是解决线程安全问题的。
异,同步的方式,在执行完同步代码块或同步方法以后,会自动释放同步监视器。
Lock的方式,必须手动地执行unlock(),才可以释放。

package threadTest;
/**
 * 生产者、消费者问题
 * 生产者将产品交给店员。而消费者从店员处取走产品。
 * 店员一次只能维持固定数量的产品(比如:20)如果生产者试图生产更多的产品,店员会叫生产者停一下。
 * 如果店中有空位放产品了再通知生产者继续生产;如果店中没有产品了,店员会告诉消费者等一下,如果店中有产品了
 * 再通知消费者取走产品。
 * 
 * 分析:
 * 是多线程问题;
 * 存在线程安全问题;
 * 共享数据是:产品的数量;
 * 使用同步机制处理操作共享数据的安全问题;
 * 涉及到了线程的通信问题。
 * 
 */
//店员
class Clerk{
	int product;
	//增加产品
	public synchronized void addProduct(){
		if(product < 20 ){
			product++;
			System.out.println(Thread.currentThread().getName()+ "生产了第"+product+"个产品");
			notify();
		}else{
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
	//减少产品
	public synchronized void reduceProduct(){
		if(product > 0 ){
			System.out.println(Thread.currentThread().getName()+ "消费了第"+product+"个产品");
			product --;
			notify();
		}else{
			try {
				wait();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
	}
}
//生产者
class Producer extends Thread{
	Clerk clerk;
	public Producer(Clerk clerk){
		this.clerk = clerk;
	}
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+":开始生产产品");
		while(true){
			try {
				Thread.sleep(50);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			clerk.addProduct();
		}
	}
}
//消费者
class Consumer extends Thread{
	Clerk clerk;
	public Consumer(Clerk clerk){
		this.clerk = clerk;
	}
	@Override
	public void run() {
		System.out.println(Thread.currentThread().getName()+":开始消费产品");
		while(true){
			try {
				Thread.sleep(100);
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			clerk.reduceProduct();
		}
	}
}

public class ProducerConsumerTest {
	public static void main(String[] args) {
		Clerk clerk = new Clerk();
		Producer p1 = new Producer(clerk);
		p1.setName("生产者1");
		Consumer c1 = new Consumer(clerk);
		c1.setName("消费者1");
		
		Consumer c2 = new Consumer(clerk);
		c2.setName("消费者2");
		
		p1.start();
		c1.start();
		c2.start();
		
	}
}


4.JVM的内存结构分析:

内存区域:方法区(Method Area),虚拟机栈(VM Stack),本地方法栈(Native Method Stack),堆(Heap),程序技术器(Program Counter Register)

5.String

5.1不可变性
给现有的字符串添加一个新的字符串,不能在原有的字符串后面添加,而必须声明一个新的内存空间,存放新的字符串。
给现有的字符串重新赋值,不能再原有的常量池对应的字符串的位置赋值,必须重新声明一个新的内存空间,存放新的字符串。
5.2连接运算
凡是字符串的连接运算中,左右两边使用了字符串的引用(而非字符串实体),此时的连接后的结果都应该在常量池中新开辟的内存空间。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值