JavaSE--多线程


前言

进程是一个应用程序(或软件)。
线程是一个进程中的执行场景/执行单元,一个进程可以启动多个线程。
一个线程一个栈,方法区内存和堆内存共享。


1、实现线程的三种方式

1.1 第一种方式:

步骤1:编写一个类继承java.lang.Thread类,重写run()方法。
步骤2:创建线程对象
步骤3:启动线程


例子:

public class Main {
    public static void main(String[] args) {
    	//创建线程对象
       NewThread nt=new NewThread();
       //启动线程
       nt.start();
       for(int i=0;i<100;i++){
            System.out.println("main线程--->"+i);
       } 
    }
}
//第一步:编写一个类继承Thread,并重写run()方法
class NewThread extends Thread{
    public void run(){
        for(int i=0;i<100;i++){
            System.out.println("新线程--->"+i);
        }
    }

}

1.2 第二种方式:

步骤1:编写一个类实现java.lang.Runnable接口,重写run()方法。
步骤2:利用Thread的Thread​(Runnable target)构造方法,创建线程对象
步骤3:启动线程


例子:

public class Main {
    public static void main(String[] args) {
    	//第二步:创建Thread对象,参数传入Callable对象
       Thread nt=new Thread(new NewThread());
       //第三步:启动线程
       nt.start();
       for(int i=0;i<100;i++){
            System.out.println("main线程--->"+i);
       } 
    }
}
//第一步:创建实现Runnable接口类,重写run()方法
class NewThread implements Runnable{
	//重写run()方法
    public void run(){
        for(int i=0;i<100;i++){
            System.out.println("新线程--->"+i);
        }
    }

}

1.3 第三种方式

步骤1:编写一个类实现java.util.concurrent.Callable接口,重写call()方法.
步骤2:创建java.util.concurrent.FutureTask未来任务类,参数传入实现Callable接口的类。
步骤3:创建线程对象Thread,参数传入FutureTask对象。
步骤4:启动线程


如何获取线程对象,利用FutureTask类的get()方法。


例子:

import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;

public class Main {
 public static void main(String[] args) throws Exception {
 		//第二步:创建java.util.concurrent.FutureTask未来任务类,参数传入实现Callable接口的类。
		FutureTask task = new FutureTask(new MyCallable());
		//第三步:创建线程对象Thread,参数传入FutureTask对象。
		Thread t = new Thread(task);
		t.setName("t");
		//第四步:启动线程
		t.start();
		//获取t线程返回值
		/*
		注意:get()方法的执行会导致当前线程阻塞,因为get()方法是为了拿到另一个线程的执行结果。只有get()方法执行结束,main线程才会继续。
		*/
		Object obj = task.get();
		System.out.println("获取t线程的结果" + obj);
		System.out.println("main线程受阻塞");
	}
}
//第一步:编写一个类实现java.util.concurrent.Callable接口,重写call()方法.
class MyCallable implements Callable{
    public Object call() throws Exception {
		Thread.sleep(1000 * 5);//模拟运行5秒
		return 0;
	}
    
}

2、Thread常用方法:

2.1 构造方法

Thread();
Thread(Runnable target);

2.2 方法

修饰返回值类型方法描述
voidstart()启动线程
staticThreadcurrentThread()获取当前线程对象的引用,在哪使用,哪就是当前线程
voidsetName()重新设置线程对象名称
StringgetName()获取线程对象的名字
staticvoidsleep(long millis)使当前线程休眠(出现在哪个线程,哪个线程休眠)
voidinterrupt()终止线程的睡眠,利用异常处理机制
voidstop()强行终止线程,容易丢失数据,不建议使用
voidjoin()合并线程,当前线程阻塞,合并的线程直到结束才继续
staticvoidyield()让位,当前线程回到就绪状态,但有可能还会抢到CPU时间片,继续执行
voidsetPriority()设置线程优先级,最高10,最低1,默认5
intgetPriority()获取线程优先级

例子:

public class Main {
    public static void main(String[] args) {
    	//创建线程对象
       Thread t=new Thread(new NewThread());
       //设置线程名字,默认Thread-0
       t.setName("NewThread线程");
       //启动线程
       t.start();
       //主线程睡眠5秒
       for(int i=5;i>0;i--){
            try{
                Thread.sleep(1000);
            }catch (InterruptedException e){
                e.printStackTrace();
            }
            //获取当前对象的名字,main方法的线程名默认是main
            System.out.println(Thread.currentThread().getName()+"线程"+i);
       } 
       //打断t线程睡眠,利用的是异常处理机制
       //执行interrupt方法,sleep出现异常,进入catch语句,从而打断睡眠。
       t.interrupt();
    }
}
//编写类,实现Runnable接口
class NewThread implements Runnable{
	//重写run方法
    public void run(){
    	//获取当前对象的名字
        System.out.println(Thread.currentThread().getName()+":begin");
        try{
        	//睡眠一天
            Thread.sleep(1000*60*60*24);
        }catch (InterruptedException e){
        	//如果不想异常输出,可以注释掉
            //e.printStackTrace();
        }
        System.out.println(Thread.currentThread().getName()+":over");
    }

}

3. Q&A

3.1 stop()方法,强行终止线程容易丢失数据,那怎么终止一个线程?

A:利用标记

public class Main{
	public static void main(String[] args){
		NewThread nt=new NewThread();
		Thread t=new Thread(nt);
		t.setName("t线程");
		t.start();
		//模拟工作5秒
		try{
			Thread.sleep(1000*5);
		}catch (InterruptedException e){
			e.printStackTrace();
		}
		//修改标记,结束线程。
		nt.run=false;
	}
}

class NewThread implements Runnable{
	boolean run=true;
	public void run(){
		for(int i=0; i<10;i++){
			if(run){
				try{
					Thread.sleep(1000);
				}catch (InterruptedException e){
					e.printStackTrace();
				}
				System.out.println(Thread.currentThread().getName()+i);
			}else{
				System.out.println(Thread.currentThread().getName()+"结束");
				return;
			}	
		}
	}
}

3.2 什么时候数据在多线程并发的情况下会存在安全问题?

三个条件:

  • 条件1:多线程并发
  • 条件2:数据共享
  • 条件3:共享数据有修改的行为
    满足以上3个条件之后,就会存在线程安全问题

局部变量+常量,不会有线程安全问题
成员变量(实例变量,静态变量):可能会有线程安全问题

3.3 怎么解决线程安全问题

在以后开发中,我们的项目都是运行在服务器中,而服务器已经将线程的定义,线程对象的创建,线程的启动等,都已经实现完了。这些代码我们都不需要编写。你要知道,你编写的程序需要放到一个多线程的环境下运行的,你更需要关注的是这些数据在多线程并发的环境下是否是安全的。

  • 第一种方案:尽量使用局部变量代替“实例变量和静态变量”。
  • 第二种方案:如果必须是实例变量,那么可以考虑创建多个对象,这样实例变量的内存不共享了。
  • 第三种方案:如果不能使用局部变量,对象也不能创建多个,这个时候只能选择synchronized了,线程同步机制(排队)。

3.4 synchronized的使用

  • 第一种:同步代码块:找共享对象
    语法结构:
synchronized (共享对象){
	//同步代码块
}
  • 第二种:在实例方法上使用synchronized,找对象锁,锁的是this
  • 第三种:在静态方法上使用synchronized,找类锁。类锁是保证静态变量安全的。

3.5 死锁怎么写?

代码要会写,只有会写了,才会在以后的开发中注意死锁,死锁很难调试。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 全国v3.0版javase加强第一阶段-第2套卷主要是指在javase基础上进行加强学习和应用。在这套卷中,学习者需要掌握更高级的Java编程知识和技巧。 首先,学习者需要对Java语言有扎实的掌握。他们应该熟练掌握Java的基本语法、数据类型、流程控制、面向对象等基础知识。在此基础上,他们还需要深入了解Java的高级特性,如多态、继承、接口等,并能够灵活运用这些知识解决实际问题。 此外,学习者还需要学习和掌握Java的核心类库。他们应该了解Java集合框架、IO流、多线程等核心类库的使用方法和原理,并能够利用这些类库进行开发和优化。 在加强第一阶段的学习中,学习者还应该注重实践。他们应该通过编写各种类型的Java程序来加深对知识的理解和掌握。这些程序可以是简单的练习题,也可以是实际的应用开发项目。 通过学习全国v3.0版javase加强第一阶段-第2套卷,学习者能够进一步提升自己的Java编程能力。他们将能够更加熟练地运用Java语言和核心类库进行开发,并能够解决更复杂、更实际的编程问题。这将为他们今后的学习和工作打下坚实的基础。 ### 回答2: 全国V3.0) JavaSE加强第一阶段-第2套卷是一套用于加强JavaSE知识的教材。JavaSE是Java平台标准版的缩写,是Java语言的基础,涵盖了Java语言的基本语法、面向对象编程、异常处理、多线程、集合框架等内容。 这套教材的目的是在第一阶段的基础上,进一步加强学生对JavaSE的理解和应用能力。它通过一系列的教学案例,让学生掌握更深入的编程技巧和方法。对于想要进一步提升Java编程能力的学生来说,这套教材是一个很好的选择。 教材中的内容包括Java中的异常处理、文件操作、网络编程、GUI界面设计等多个方面。 这些内容都是Java编程中非常重要的知识点,掌握了这些知识,学生可以更加灵活地运用Java语言来解决实际问题。 教材的设计符合教育教学规律,注重理论与实践相结合,通过实际的编程案例,帮助学生巩固理论知识,并且锻炼解决实际问题的能力。 总之,全国V3.0) JavaSE加强第一阶段-第2套卷是一套旨在加强学生对JavaSE知识理解和应用能力的教材。它涵盖了JavaSE的核心内容,通过实例教学帮助学生锻炼编程能力。对于想要进一步提升Java编程水平的学生来说,这套教材是一个非常实用和有效的学习工具。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值