黑马程序员-------Java笔记--------多线程基础练习2题

时间:2021-11-16 00:27:16

------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------

  • 多线程(提高效率)
    • 指应用程序有多条执行路径
    • 进程:正在运行的程序
    • 线程:进程的执行单元,一条执行的路径
  • 多线程的2种实现方式
    • 创建一个类继承Thread类,重写run方法,让线程启动。
    • 创建一个类实现runnable接口,重写run方法,创建类的实例,把类的实例做为Thread的构造参数传递,创建Thread对象
  • 区别
    • 实现接口,避免了单继承的局限性
    • 实现接口只创建了一个对象,更好的实现了数据和操作的分离
  • 安全问题
    • 因为线程运行的随机性和延迟性,导致共享数据出现问题
    • 有没有共享数据,对共享数据操作是不是多条语句,是否在多线程环境中
    • 通过加同步锁的方式来解决。
package demo;

//模拟三个老师同时发80份笔记
/**
* 思路:
* 1.写一个类来实现Runnable接口,重写run方法
* 2.定义共享数据80份笔记,私有,静态。
* 3.模拟发笔记,用循环,条件是笔记数量>0;
* 4.为了保证线程安全,加上一把锁。
* 5.在main方法中创建一个资源对象,
* 6.开启三个线程。
*
*/
public class Demo19 {
public static void main(String[] args) {
//创建共享资源对象
MyThread3 my = new MyThread3();
//创建3个线程并开启
new Thread(my,"老师1").start();
new Thread(my,"老师2").start();
new Thread(my,"老师3").start();
}
}

class MyThread3 implements Runnable {
//设置共享资源
private static int s = 80;
//重写run方法
public void run() {
//发笔记
while (s > 0) {
//加上一把锁
synchronized (MyThread3.class) {
try {
//让进来的线程睡眠0.1秒
Thread.sleep(100);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//判断是否还有笔记
if(s>0){
System.out.println(Thread.currentThread().getName() + "正在发送第"
+ s + "份笔记");
s--;//发一份就减一份
}
}
}
}
}

*****************************************************************************************************************************************************

package demo;
//创建10个线程,线程一从1加到10,线程2从11加到20....最后把十个线程的结果相加。
/**
* 思路:
* 1.创建一个类,实现runnable接口,
* 2.定义2个成员变量,线程的初始值,线程的总量,
* 3.定义一个设置线程初始值的方法和获取线程总量的方法
* 4.重写run方法,每一个线程除了初始值不一样外,相加的类容都一样,获取单个线程的量。
* 5.将每个线程的量都相加。
* 6.在,main方法中创建共享数据对象
* 7.创建10个线程的的数组
* 8.遍历数组,获取每一个线程,给其赋初始值,
* 9.开启线程,并让线程插队
*
*/
public class Demo20 {
public static void main(String[] args) throws InterruptedException {
//创建共享资源数据
MyThread4 my = new MyThread4();
//创建10个线程数组
Thread[] arr=new Thread[10];
//遍历该数组
for (int i = 0; i < arr.length; i++) {
//创建线程
Thread t=new Thread(my,"线程"+i);
//设置该线程的初始值
my.setStr(10*i+1);
//开启线程
t.start();
//线程等待
t.join();
}
System.out.println(MyThread4.getSum());
}
}
class MyThread4 implements Runnable{
private int str;//线程的初始值
private static int sum;//所有线程数量和
//设置线程赋初始值方法
public void setStr(int str){
this.str=str;
}
//获取所有线程的数量的方法
public static int getSum(){
return sum;
}
//重写run方法
public void run() {
//设置初始值
int num=0;
//获取一个线程的量
for (int i = 0; i < 10; i++) {
num+=str+i;
}
//调用添加方法
add(num);

}
//把每一个线程的量相加
private void add(int num) {
sum+=num;

}

}