怎么创建多线程?
方式1:继承Thread类的方式进行实现
步骤1:继承Thread类
步骤2:重写run方法
步骤3:创建MyThread的对象,调用start方法启动线程
MyThread类
public class MyThread extends Thread {
// 重写run方法,线程要执行的代码
// 方式1:继承Thread类的方式进行实现
// 步骤1:继承Thread类
// 步骤2:重写run方法
@Override
public void run() {
for (int i = 0; i <= 50; i++) {
// setName("测试");
System.out.println(getName() + ":" + i);
}
}
}
测试类
package day30_多线程;
public class Demo01 {
// 步骤3:创建MyThread的对象,调用start方法启动线程
public static void main(String[] args) {
MyThread t1 = new MyThread();
t1.setName("线程1");// 给创建设置名字
// 开启线程--此处需要注意:不能直接调用run方法,否则就是对象的创建和方法的调用
t1.start();
for (int i = 0; i <= 50; i++) {
System.out.println("main" + i);
}
}
}
方式2:实现Runnable接口的方式进行实现
1.自定义一个类实现Runnable接口
2.重写run方法
3.创建自定义类的对象,将其作为参数
4.创建一个Thread对象,参数为3,并开启线程
MyRunnable类
public class MyRunable implements Runnable {
@Override
public void run() {
for (int i = 0; i <= 50; i++) {
// getName()为Thread类的方法,不能直接使用getName()方法
// MyRunable和Thread类没有继承关系
// 通过Thread的静态方法获取当前线程对象后获取方法名字
Thread t1 = Thread.currentThread();
System.out.println(t1.getName() + ":" + i);
}
}
}
测试类
public class Demo02 {
// 方式2:实现Runnable接口的方式进行实现
// 1.自定义一个类实现Runnable接口
// 2.重写run方法
// 3.创建自定义类的对象,将其作为参数
// 4.创建一个Thread对象,参数为3,并开启线程
public static void main(String[] args) {
// 创建MyRunable的对象,表示多线程要执行的任务
MyRunable r1 = new MyRunable();
// 创建线程对象
Thread t1 = new Thread(r1);
Thread t2 = new Thread(r1);
t1.setName("子线程1");
t2.setName("子线程2");
t1.start();// 开启线程
t2.start();
// 设置主线程的名字
Thread mainThread = Thread.currentThread();
mainThread.setName("main主线程");
for (int i = 0; i <= 50; i++) {
System.out.println(mainThread.getName() + ":" + i);
}
}
}
方式3:实现Callable接口的方式进行实现线程(和方式2相同)
MyCallable类
import java.util.concurrent.Callable;
public class MyCallable implements Callable<Integer> {
//线程要执行的代码
// 步骤1:创建一个实现类来实现Callable接口
// 步骤2:重写ca11方法(有返回值,表示多线程执行的任务的返回值)
@Override
public Integer call() throws Exception {
int sum = 0;
for (int i = 0; i <= 100; i++) {
sum += i;
}
return sum;
}
}
测试类
package day30_多线程;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.FutureTask;
public class Demo03 {
public static void main(String[] args) throws InterruptedException, ExecutionException {
// 方式3:实现Callable接口的方式进行实现线程---和方式2相同
// 特点:可以获取到多线程的运行结果
// 步骤3:创建实现类对象
// 步骤4:创建FutureTask类型的对象(管理多线程执行后的结果)
// 步骤5:Thread类的对象的创建,并启动
// 创建Callable实现类对象(表示多线程要执行的任务)
MyCallable m1 = new MyCallable();
// 创建FutureTask对象(作用管理多线程的运行结果)
FutureTask<Integer> ft = new FutureTask<Integer>(m1);
// 创建线程对象
Thread t1 = new Thread(ft);
// 启动线程
t1.start();
// 获取多线程运行的结果
Integer num = ft.get();
System.out.println(num);
}
}
多线程的常见方法:
getName()方法
getName获取当前线程的名称
如果不是继承自Thread的类,则需要通过
Thread tmain = Thread.currentThread();
通过Thread的静态currentThread();方法获取当前线程对象
然后再通过getName()方法获取方法名
如果没有给线程设置名字,线程也有存在默认名称
格式:Thread-X(X的序号从0开始)
setName()方法
void setName(String name)
通过父类的单参的构造方法设置线程的名字,进行设置线程名称。
给线程设置名字
Thread.currentThread() 方法
Thread.currentThread();获取当前的线程
Thread.sleep()方法
Thread.sleep(XXX);让指定的线程休眠多少毫秒
细节:哪条线程执行到此方法,那么哪条线程就会在这里停留对应的时间
参数为毫秒 1秒=1000毫秒
当时间到了以后,线程会自动的醒来,继续执行下面的代码
MyThread类
public class MyThread extends Thread {
public MyThread(String name) {
super(name);
}
public MyThread() {
}
//重写run方法,线程要执行的代码
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
System.out.println(getName() + ":" + i);
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
测试类
package day30_多线程方法;
public class Demo01 {
public static void main(String[] args) throws InterruptedException {
// getName():获取此线程名字
// 细节:如果没有给线程设置名字.线程也会有默认名称
// 格式:Thread-X(X的序号从0开始)
// void setName(String name)设置线程的名字,构造方法进行设置线程名称
// Thread.currentThread();获取当前的线程
// Thread.sleep(XXX);让指定的线程休眠多少毫秒
//细节1:哪条线程执行到此方法,那么哪条线程就会在这里停留对应的时间
// 参数为毫秒 1秒=1000毫秒
// 当时间到了以后,线程会自动的醒来,继续执行下面的代码
MyThread m1 = new MyThread();
m1.setName("线程1");
m1.start();
MyThread m2 = new MyThread("线程2");
m2.start();
// 主线程
//哪条线程执行到此方法,此时获取到的就是哪个线程的对象
Thread tmain = Thread.currentThread();
System.out.println(tmain.getName());
System.out.println("1111");
Thread.sleep(3000);
System.out.println("2222");
}
}
getPriority()方法
getPriority() 获取优先级
setPriority() 方法
setPriority() 设置优先级
范围1~10,默认优先级为5
数字越大优先级越高,但不是一定先执行完
MyRunnable类
public class MyRunnable implements Runnable {
@Override
public void run() {
for (int i = 1; i <= 100; i++) {
System.out.println(Thread.currentThread().getName() + "@" + i);
}
}
}
测试类
public class Demo02 {
// getPriority() 获取优先级
// setPriority() 设置优先级
public static void main(String[] args) {
MyRunnable runnable = new MyRunnable();
Thread t1 = new Thread(runnable, "线程1");
Thread t2 = new Thread(runnable, "线程2");
// getPriority() 获取优先级
// 范围1~10,默认优先级为5
System.out.println(t1.getPriority());
System.out.println(t2.getPriority());
System.out.println(Thread.currentThread().getPriority());
// 数字越大优先级越高,但不是一定先执行完
t1.setPriority(1);
t2.setPriority(10);
t1.start();
t2.start();
}
}
setDaemon(true)设置守护线程
//守护线程
public class Demo03 {
public static void main(String[] args) {
MyThread1 t1 = new MyThread1();
MyThread2 t2 = new MyThread2();
t1.setName("女神线程");
t2.setName("(备胎)守护线程");
// 在调用start()方法前,
// 调用setDaemon(true)将t2线程标记为守护线程
t2.setDaemon(true);
t1.start();
t2.start();
}
}
class MyThread1 extends Thread {
@Override
public void run() {
for (int i = 0; i <= 10; i++) {
System.out.println(getName() + "@" + i);
}
}
}
class MyThread2 extends Thread {
@Override
public void run() {
for (char c = 'A'; c <= 'Z'; c++) {
System.out.println(getName() + "@" + c);
}
}
}
用户线程:我们平常创建的普通线程;
守护线程:用来服务于用户线程的线程,在JVM中,所有非守护线程都执行完毕后,无论有没有守护线程,虚拟机都会自动退出;而守护线程执行结束后,虚拟机不会自动退出。守护线程不一定会执行完,但是普通线程一定会执行完
Thread.yield()方法
让出当前的cpu的执行权,让结果更加均匀一点,也不是绝对均匀
当前的线程让出执行权后,再次进行抢夺资源也可能会抢到
public class Demo04 {
public static void main(String[] args) {
MyThread3 t1 = new MyThread3("线程1");
MyThread3 t2 = new MyThread3("线程2");
t1.start();
t2.start();
}
}
class MyThread3 extends Thread {
public MyThread3(String string) {
super(string);
}
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
System.out.println(getName() + "@" + i);
// 让出当前的cpu的执行权,让结果更加均匀一点,也不是绝对均匀
// 当前的线程让出执行权后,再次进行抢夺资源也可能会抢到
Thread.yield();
}
}
}
线程插队:join()方法
如果想要先执行线程1,再执行main方法,使用join,插队
将线程t1添加到当前线程的前面执行
//join方法
public class Demo06 {
public static void main(String[] args) throws InterruptedException {
// 如果想要先执行线程1,再执行main方法,使用join,插队
MyThread4 t1 = new MyThread4();
t1.setName("线程");
t1.start();
// 将线程t1添加到当前线程的前面执行
t1.join();
for (int i = 0; i < 100; i++) {
System.out.println("main@" + i);
}
}
}
class MyThread4 extends Thread {
@Override
public void run() {
for (int i = 0; i <= 100; i++) {
System.out.println(getName() + "@" + i);
}
}
}