2021-10-20 pta习题(5) 多线程

目录

7-1 多线程计算 (30 分)

输入格式:

输出格式:

输入样例:

输出样例:

答案: 

synchronized

synchronized与Lock的区别

7-2 试试多线程 (30 分)

输入格式:

输出格式:

输入样例:

输出样例:

答案: 

static

7-3 创建一个倒数计数线程 (40 分)

输入格式:

输出格式:

输入样例:

输出样例:

答案: 

Thread.sleep()


7-1 多线程计算 (30 分)

已知某学校有n名教师,学校有m名学生,学校搞学生民意调查,每一位学生为每一位老师都打分,学生所打的所有的分数都集中到一个数组中。数据存放规律是,前m个数据是对1号老师的打分,接下来m个数据是对2号老师的打分,以此类推。请设计一个多线程的算法,计算出每一位老师的总打分。

输入格式:

第一行输入教师数,第二行输入学生数,第三行输入所有n*m个打分(整型),各个分数之间以一个空格分隔

输出格式:

按照教师原来的顺序,每行输出每一位老师的得分

输入样例:

在这里给出一组输入。例如:

2
3
1 2 3 4 5 6

输出样例:

在这里给出相应的输出。例如:

6
15

答案: 

import java.util.*;

public class Main {
    //一定要抛出异常,否则是部分正确
	public static void main(String[] args) throws InterruptedException{
		Scanner sc = new Scanner(System.in);
		int teacher =sc.nextInt();
		int student =sc.nextInt();
		
		//集合类型,方便删除和移动元素(此题要删除和移动元素)
		ArrayList<Integer> num=new ArrayList<Integer>();
		for(int i=0;i<student*teacher;i++) {
			int a = sc.nextInt();
			num.add(a);
		}
		
		Score score=new Score(num,teacher, student);
		Thread t[]=new Thread[teacher];
		for(int i=0;i<t.length;i++) {
			t[i]=new Thread(score);
			t[i].start();
		}
	}
}

class Score implements Runnable{
	int teacher,student;
	ArrayList<Integer> num=new ArrayList<Integer>();

	public Score(ArrayList<Integer> num, int teacher, int student) {
		//必须是this.XXX,否则结果是0,0
		this.num = num;
		this.teacher = teacher;
		this.student = student;
	}

	public synchronized void run() {
		int sum = 0;
		for (int i = 0; i < student; i++) {
			//返回此列表中指定位置的元素,并相加
			sum += num.get(0);
			//删除该列表中指定位置的元素
			num.remove(0);
		}
		System.out.println(sum);
	}
}

集合ArrayList

        remove(),get(),add()

多线程

抛出异常

synchronized

结果说明
        当两个并发线程(thread1和thread2)访问同一个对象(Score)中的synchronized代码时在同一时刻只能有一个线程得到执行,另一个线程受阻塞,必须等待当前线程执行完这个代码块以后才能执行该代码块。Thread1和thread2是互斥的,因为在执行synchronized代码块时会锁定当前的对象,只有执行完该代码块才能释放该对象锁,下一个线程才能执行并锁定该对象。

Java中Synchronized的使用icon-default.png?t=L9C2https://blog.csdn.net/qq_38011415/article/details/89047812

synchronized与Lock的区别

        java内置锁是一个互斥锁,这就是意味着最多只有一个线程能够获得该锁,当线程A尝试去获得线程B持有的内置锁时,线程A必须等待或者阻塞,知道线程B释放这个锁,如果B线程不释放这个锁,那么A线程将永远等待下去。(目的:只有一个线程可执行)

java中同步锁synchronized与Lock的区别icon-default.png?t=L9C2https://blog.csdn.net/gm371200587/article/details/88173030

7-2 试试多线程 (30 分)

编写4个线程,第一个线程从1加到25,第二个线程从26加到50,第三个线程从51加到75,第四个线程从76加到100,最后再把四个线程计算的结果相加。

输入格式:

输出格式:

最终结果

输入样例:

输出样例:

5050

答案: 

public class Main {
	 public static void main(String[] args){
		 Add a1 = new Add(1);
		 Add a2 = new Add(26);
		 Add a3 = new Add(51);
		 Add a4 = new Add(76);
		 try {
		 a1.start();
		 a2.start();
		 a3.start();
		 a4.start();
		 
		 a1.join(); //等待当前的线程执行结束
		 a2.join();
		 a3.join();
		 a4.join();
		 }catch(Exception e) {
			 e.printStackTrace();
		 }
		 
		 Add.print();
	 }
}

class Add extends Thread{		
	 public static int sum=0;
	 public int count=0;
    //public static int count=0;不对
    //静态变量被所有对象共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。
	 Add(){
		 
	 }
	 
	 Add(int temp){
		 count = temp;
	 }
	 
	 //重写run方法
	 public void run() {	
		 int i=0;
		 while(i<25) {
			 sum+=count;
			 count++;
			 i++;
		 }
	 }
	 
	 public static void print() {
		 System.out.println(sum);
	 }
}

static

static修饰成员变量:

        static修饰的变量也称为静态变量,静态变量和非静态变量的区别是:静态变量被所有对象共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。

        static成员变量的初始化顺序按照定义的顺序进行初始化。

java static关键字的作用是什么?icon-default.png?t=L9C2https://www.php.cn/java/guide/462574.html

 

7-3 创建一个倒数计数线程 (40 分)

创建一个倒数计数线程。要求:1.该线程使用实现Runnable接口的写法;2.程序该线程每隔0.5秒打印输出一次倒数数值(数值为上一次数值减1)。

输入格式:

N(键盘输入一个整数)

输出格式:

每隔0.5秒打印输出一次剩余数

输入样例:

6

输出样例:

在这里给出相应的输出。例如:

6
5
4
3
2
1
0

答案: 

import java.util.Scanner;
public class Main {

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int N=sc.nextInt();
        Test t=new Test(N);
        Thread th=new Thread(t);
        th.start();
    }
}
class Test implements Runnable {
	public int M;
	Test(){
		
	}
	
	Test(int N){
		M = N;
	}
    public void run() {
        for(int i=M;i>=0;i--){
            System.out.println(i);
            try 
               {
                Thread.sleep(500);
               } catch (InterruptedException e) {
                e.printStackTrace();
               }
        }
    }
}

Thread.sleep()

    • static voidsleep(long millis)

      使当前正在执行的线程以指定的毫秒数暂停(暂时停止执行),具体取决于系统定时器和调度程序的精度和准确性。

      static voidsleep(long millis, int nanos)

      导致正在执行的线程以指定的毫秒数加上指定的纳秒数来暂停(临时停止执行),这取决于系统定时器和调度器的精度和准确性。

 

  • 7
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值