书山小站

记录我的程序人生

[JAVA]多线程编程-第一式

JAVA多线程编程

JAVA

并发和并行

  • 并行:在同一时刻,有多个指令在多个CPU上同时执行
  • 并发:在同一时刻,有多个指令在单个CPU上交替执行

进程和线程

  • 进程:正在运行的程序

    • 独立性:独立运行的单位,也是系统分配资源和调度的独立单位
    • 动态性:进程动态产生,动态消亡
    • 并发性:可以同其他进程一起并发执行
  • 线程:进程中单个顺序控制流,是一条执行路径

多线程实现方式

  • 继承Thread类的方式进行实现
  • 实现Runnable接口的方式进行实现
  • 利用Callable和Future接口方式实现
方式一:继承Thread类
  • 定义一个继承Thread的类
package class_1_threw;

public class Mythread extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 100 ; i++){
            System.out.println("线程开始了"+i);
        }
    }
}
package class_1_threw;

public class main {
    public static void main(String[] args) {
        Mythread t1 = new Mythread();
        Mythread t2 = new Mythread();
        t1.start();
        t2.start();
    }
}
线程开始了0
....
线程开始了22
.....
线程开始了36
....
线程开始了43
线程开始了5
线程开始了44
  • 随机性

Q: 为什么要重写run方法?

A: 因为run()方法是用来封装呗线程执行的代码

Q: run() 和 start() 有什么区别

A:如果执行run则是仅仅是创建对象调用的方法并没有开启方法

      start开启一条线程

由jvm调用线程的run方法

方式2 Runnable接口
  • 定义类继承Runnable接口
  • 在类中重写run()方法
  • 创建类的实例对象
  • 创建Thread类对象,把继承Runnable接口类的对象作为构造方法参数
package class_2_Runnable;

public class main {
    public static void main(String[] args) {
        MyRunnable mr = new MyRunnable();//创建参数对象
        Thread t1 = new Thread(mr); // 创建线程
        Thread t2 = new Thread(mr); // 创建线程
        t1.start();
        t2.start();
    }
}
package class_2_Runnable;

public class MyRunnable implements Runnable{

    @Override
    public void run() {
        // 线程启动后执行的代码
        for (int i = 0; i < 100; i++) {
            System.out.println("Runnable实现多线程"+i);
        }
    }
}
Runnable实现多线程0
Runnable实现多线程1
Runnable实现多线程0
Runnable实现多线程2
Runnable实现多线程1
Runnable实现多线程3
Runnable实现多线程2
Runnable实现多线程4

方式三:Callable和Future

  • 定义一个类实现Callable接口
  • 在类中实现call()方法
  • 创建Callable实现类的对象
  • 创建Future的实现类实现类FutureTask对象,把Callable实现类的对象作为构造方法的参数
package class_4_Called;

import java.util.concurrent.Callable;

public class Called implements Callable<String> {
    @Override
    public String call() throws Exception {
        for (int i = 0; i < 100; i++) {
            System.out.println("怪物接受攻击伤害"+i);
        }
        return "怪物死亡"; // 返回值就表示线程运行完之后的结果
    }
}
package class_4_Called;

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

public class main {
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        Called m = new Called();  //线程
        FutureTask<String> f = new FutureTask<>(m); //中介
        Thread t1 = new Thread(f);
        t1.start();
        System.out.println(f.get());
    }
}

...

....

..

怪物接受攻击伤害86
怪物接受攻击伤害87
怪物接受攻击伤害88
怪物接受攻击伤害89
怪物接受攻击伤害90
怪物接受攻击伤害91
怪物接受攻击伤害92
怪物接受攻击伤害93
怪物接受攻击伤害94
怪物接受攻击伤害95
怪物接受攻击伤害96
怪物接受攻击伤害97
怪物接受攻击伤害98
怪物接受攻击伤害99
怪物死亡

Thread一些的方法

  • getName() 获取当前线程名称
package class_5_Thread_method;

public class main {
    public static void main(String[] args) {
        getnamess a = new getnamess();
        a.start();
        new getnamess().start();
        new getnamess().start();
    }
}
Thread-1
Thread-2
Thread-0
package class_5_Thread_method;

public class getnamess extends Thread{
    @Override
    public void run() {
        Thread t = currentThread();
        System.out.println(t);
//        String a = getName();
//        System.out.println(a);
    }
}
  • Sleep 使当前执行的线程以指定的毫秒数暂停
public class main {
    public static void main(String[] args) throws InterruptedException {
//        getnamess a = new getnamess();
//        a.start();
//        new getnamess().start();
//        new getnamess().start();
        for (int i = 0; i < 20; i++) {
            Thread.sleep(1000);
            System.out.println(i);
        }
    }
}
  • setname 设置线程名称

    package class_5_Thread_method;
    
    public class main {
        public static void main(String[] args) {
            getnamess a = new getnamess();
            a.setName("阿伟")
            a.start();
            new getnamess().start();
            new getnamess().start();
        }
    }

发表评论

电子邮件地址不会被公开。 必填项已用*标注