黑马程序员_多线程

---------------------android培训java培训、java学习型技术博客、期待与您交流! -------------------

线程是程序执行的一条路径, 一个进程中可以包含多条线程
多线程并发执行可以提高程序的效率, 可以同时完成多项工作
jvm启动的时候会有一个进程java.exe
该进程中至少有一个线程负责java程序的执行,而且这个线程的代码存在于main方法中,该线程称之为主线程。

扩展知识:
其实更细节说虚拟机,jvm启动不止一个线程,还有一个负责垃圾回收机制的线程

创建新线程的方法:
方法一:
1.继承Thread,步骤如下:
a、定义类继承Thread
b、重写run()方法
c、把新线程要做的事写在run方法中
d、创建线程对象
e、开启新线程, 内部会自动执行run方法
代码如下:将类声明为Thread的子类

//1、定义类继承Thread类
class ThreadDemo extends Thread{
	//2、重写run()方法
	public void run(){	
		System.out.println("线程运行了");
	}
}
class Demo{
	public static void main(String[] args){
		ThreadDemo td = new ThreadDemo();
		//td.run();	
		//仅仅是对象调用方法,线程创建了,并没有执行,该方法被主函数所调用,只有执行完才会执行下面的代码。
		td.start();	//开启了线程,并执行该线程的run()方法
	}
}

2.实现Runnable接口的步骤:
a、定义类实现Runnable接口;
b、覆盖Runnable接口中的run()方法,将线程要运行的代码存放在run()方法中
c、通过Thread类建立线程对象;
d、将Runnable接口的子类对象作为实际参数传递给Thread类的构造函数;
    为什么要将Runnable接口的子类对象传递给Thread类的构造函数?
    因为,自定义的run()方法所属的对象是Runnable接口的子类对象,所以要让线程去执行指定对象的的run()方法,就必须明确该run()方法的对象。
e、调用Thread类的start()方法开启线程并调用Runnable接口子类的run()方法。
代码如下:

class ThreadDemo implements Runnable {
	public void run(){
		System.out.println("Runnable接口实现方式");
	}
}
class Demo {
	public static void main(String[] args){
		//创建Runnable接口的子类对象
		ThreadDemo td = new ThreadDemo();
		//将Runnable接口的子类对象传给Thread类的构造函数
		Thread t = new Thread(t);
		t.start();	//启动线程
	}
}

多现程的运行出现了安全问题
出现的原因:当多条语句,在操作同一共享数据时,一个线程对多条语句只执行一部分,还没有执行完,另一个线程参与进来执行,导致共享数据的错误。
解决办法:
 对多条操作共享数据的语句,在某一时间段,只能让一个线程访问,java对于多线程的安全问题提供了专业的解决方式,就是同步代码块。


同步函数用的是哪一个锁呢?
函数需要被对象调用,那么函数都有一个所属对象引用,就是this,所以同步函数使用的锁是this

如果同步函数被静态static修饰,使用的锁是什么呢?
通过验证,发现不再是this。因为静态方法中也不可以定义this
静态进内存时,内存中没有本类对象,但是一定有该类对应的字节码文件,即类名.class,访问对象的类型是class
静态的同步方法,使用的锁是该方法所在类的字节码文件对象,也就是 类名.class (面试可能问到的问题)

class Single {
	private static Single s = null;	//创建类的引用,先不创建对象
	private Single(){}	//私有构造函数

	public static Single getInstance(){	//提供公共的访问
		if (s==null){	//判断引用是否为空
			synchronized(Single.class){	//同步代码块,里面的对象是该类所属对象的字节码
				if (s==null){	//如果引用为空
					s = new.Single();	//则创建对象
				}
			}
		}
		return s;	//返回对象引用
	}
}

为了解决懒汉式单例设计模式多线程访问的问题,用双重判断加同步代码块,以解决其安全问题。
这种解决办法也存在一定的安全隐患,概率很低。

黑马程序员多线程练习题主要包括两个问题。第一个问题是如何控制四个线程在打印log之前能够同时开始等待1秒钟。一种解决思路是在线程的run方法中调用parseLog方法,并使用Thread.sleep方法让线程等待1秒钟。另一种解决思路是使用线程池,将线程数量固定为4个,并将每个调用parseLog方法的语句封装为一个Runnable对象,然后提交到线程池中。这样可以实现一秒钟打印4行日志,4秒钟打印16条日志的需求。 第二个问题是如何修改代码,使得几个线程调用TestDo.doSome(key, value)方法时,如果传递进去的key相等(equals比较为true),则这几个线程应互斥排队输出结果。一种解决方法是使用synchronized关键字来实现线程的互斥排队输出。通过给TestDo.doSome方法添加synchronized关键字,可以确保同一时间只有一个线程能够执行该方法,从而实现线程的互斥输出。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *2* *3* [黑马程序员——多线程10:多线程相关练习](https://blog.csdn.net/axr1985lazy/article/details/48186039)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 100%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值