ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

多线程的三种实现方式

2021-01-22 09:02:08  阅读:112  来源: 互联网

标签:方式 Thread System 线程 println 三种 多线程 public out


一、继承Thread类,实现多线程

1.demo01
public class ThreadDemo01 extends Thread{
private static int i=10;
@Override
public synchronized void run() {
if(i>0){
System.out.println(currentThread().getName()+"============="+i);
i--;
}else {
System.out.println("寿终正寝");
}
}

public static void main(String[] args) {
for(int n=0;n<20;n++){
ThreadDemo01 thread = new ThreadDemo01();
thread.start();
}
}
}
可解决商品商品超卖问题,也可选择使用乐观锁加版本号方式处理;
2.demo02
public class ThreadDemo01 extends Thread{
private int i;
public void run(){
for(; i<100 ;i++){
System.out.println(getName() +" "+ i);
}
}
public static void main(String[] args) {
for(int i = 0 ;i<100; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
if (i == 20) {
new ThreadDemo01().start();
new ThreadDemo01().start();
}
}
}
}
总结:该例中第一次出现的变量i是实例变量,而每次创建线程对象时候,Thread-0和Thread-1两个线程对象不能共享实例变量i。即使用继承Thread方法创建线程对象时,多个线程之间无法共享线程类的实例变量。可拷贝代码运行后查看数据结果。

二、基于Runnable接口实现多线程

public class ThreadDemo02 implements Runnable{
  
private int i;

public void run(){
for(; i<100 ;i++){
//当线程类实现Runnable接口时,只能通过Thread.currentThread()方法获得当前线程
System.out.println(Thread.currentThread().getName() +" "+ i);
}
}

public static void main(String[] args) {
for(int i = 0 ;i<100; i++){
System.out.println(Thread.currentThread().getName()+" "+i);
if(i==20){
ThreadDemo02 td = new ThreadDemo02();
//创建两个Thread对象,并且均把Runnable接口实例对象作为target
new Thread(td).start();
new Thread(td).start();
}
}
}
}
总结:从运行的结果可以看到实例变量i的输出是连续的。也就是使用Runnable接口创建的多个线程是可以共享线程类的实例变量,这是因为多个线程可以共享同一个target,所以多个线程可以共享同一个线程类(target类)的实例属性。

三、Callable实现多线程

public class ThreadDemo03 implements Callable {
  
public Integer call(){
int i = 5;
for( ; i<100 ; i++){
System.out.println(Thread.currentThread().getName() + "的循环变量i的值:" +i);
}
//call()方法可以有返回值
return i;
}
public static void main(String[] args) {
//创建Callable对象
ThreadDemo03 cd = new ThreadDemo03();

//使用FutureTask来包装Callable对象
FutureTask<Integer> task = new FutureTask<Integer>(cd);
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() + "的循环变量i的值:" + i);
if (i == 20) {
//实质还是以Callable对象来创建并启动线程
new Thread(task, "有返回值的线程").start();
}
}
try {
System.out.println("子线程的返回值" + task.get());
} catch (Exception e) {
e.printStackTrace();
}
}
}
总结:三种线程的启动归根结底都是通过调用线程类中的start方法。后面两种则是调用线程类中Thread(Runable target)的方式,第二种直接是实现了runable接口类,只需传入相应的实例对象,第三种传入的callable接口,借助中间接口furtuetask接口,该接口实现了runable接口和furture接口,实例化后也是一个runable的实例,启动线程后传入第三种的实例变量即可,第三种有返回值,均是启动线程后调用run方法或call方法


标签:方式,Thread,System,线程,println,三种,多线程,public,out
来源: https://www.cnblogs.com/wangdsh/p/14311476.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有