【Java】多线程 语法 使用

在java中使用多线程有三种方式。

1.继承Thread类;

2.实现Runnable接口;

3.匿名内部类;


第一种一般不用,因为java只允许单继承,万一这个业务类有父类就无法继承了。

第二种如下:

public class ThreadBusiness implements Runnable{

	@Override
	public void run() {
		service();
	}

	public void service(){
		System.out.println("start");
		System.out.println("end");
	}
	
	public static void main(String args[]){
		Thread ttThread = new Thread(new ThreadBusiness());
		ttThread.start();
	}
}

这种写法对应的业务类通常比较复杂,类实现本身有很多的业务代码和方法。但又要求这个类具有并发的特征。

第三种如下:

Thread t1 = new Thread(new Runnable() {
				@Override
				public void run() {
					c.g();
				}
			});
这种一般用于并发处的代码比较简单,比如仅仅是对一个函数的调用,针对函数。因为如果并发类的内容很多,匿名内部类的可读性太差了。但是如果匿名类实现很简单,推荐这种写法,主要是类的数目变少了。

一旦定义了线程类,就可以调用这个线程的方法,比如start()。注意,线程只能开始一次,否则报错。

线程里的run方法本质是这个线程的执行入口,就像一个java程序的入口是main函数一样。

使用多线程可以方便程序设计,但是会带来一些问题。

尤其是在多线程共享变量的情况,典型的是对同一个具体线程的聚合。就是创建具有并发特性的业务类,然后把该业务类的实例当做是新建的线程实例的参数,运行多次。这每一个线程相当于是在调用同一个业务对象的业务方法。就会产生一些问题,比如覆盖写,一个写的线程读取了一个没有被另一个线程把最新值写回的值。那么之前的更新就会被覆盖。例子:

public class ThreadBusiness implements Runnable{

	private int account = 0;
	
	@Override
	public void run() {
		service();
	}

	public void service(){
		System.out.println("start");
		int i = account;
		
		try {
			Thread.sleep(1);//计算时间
			i = i + 1;
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		
		this.account = i;
		System.out.println("end");
	}
	
	public static void main(String args[]) throws InterruptedException{
		ThreadBusiness t = new ThreadBusiness();
		for(int i = 0; i < 10; i++){
			Thread t1 = new Thread(t);
			t1.start();
		}
		Thread.sleep(100);
		System.out.println(t.getAccount());
	}

	public int getAccount() {
		return account;
	}

	public void setAccount(int account) {
		this.account = account;
	}
}


执行了10次的自增操作,最后结果是2。在业务方法内部加入1毫秒的等待模拟业务执行过程。可以看到结果不对。这就是直接对共享变量多线程时存在的问题。

有个问题,上面的10个线程实际上是执行了业务线程10次,但是线程不知只能start一次吗?也就是业务线程为什么可以执行10次?

这个需要搞清楚run方法和start方法的区别。

run方法并不是基于并发的实现,而是顺序实现,即必须等待当前线程结束才会执行。start方法才可以开启线程。在start方法实现的内部,先做了并发的启动,然后才调用实际的run方法的。run只是描述了要做什么,并不能并发。

如果把上述程序的start改为run,结果就是:


可以看到,每一个线程都是顺序完成的。或者说,这里本身就没有多线程的概念,相当于一个for循环的顺序执行。要启动多线程,必须使用start方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中的for循环和多线程是两个同的概念,我可以为你分别介一下。 1. Java中的for循环: for循是一种常用的循环结构,用于重复执行一段代码块。它的语法格式如下: ``` for (初始化表达式; 循环条件; 更新表达式) { // 循环体 } ``` 初始化表达式用于初始化循环变量,循环条件用于判断是否继续执行循环,更新表达式用于更新循环变量的值。在每次循环迭代时,先执行循环体,然后执行更新表达式,再判断循环条件是否满足,如果满足则继续下一次迭代,否则退出循环。 2. Java中的多线程: 多线程是指在一个程序中同时执行多个线程,每个线程可以独立执行不同的任务。Java提供了多种方式来创建和管理多线程,其中最常用的方式是通过继承Thread类或实现Runnable接口来创建线程。具体步骤如下: - 继承Thread类:创建一个继承自Thread类的子类,并重写run()方法,在run()方法中定义线程要执行的任务。 - 实现Runnable接口:创建一个实现了Runnable接口的类,并实现其run()方法,在run()方法中定义线程要执行的任务。 - 创建线程对象:通过创建Thread类的实例或传入Runnable对象创建线程对象。 - 启动线程:调用线程对象的start()方法来启动线程,start()方法会自动调用run()方法。 多线程可以提高程序的并发性和响应性,但也需要注意线程安全和资源共享的问题。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值