1.继承Thread,重写 run()方法。
2.实现Runnable,实现run()方法。
建议使用实现Runnable接口的方式,因为Java的机制是单继承,多实现
并且我们可以通过setPriority()来设置该线程的执行优先级
/**
* 通过继承Thread来实现多线程的类
*/
public class ThreadA extends Thread{
public void run(){
System.out.println("我是一个通过extends Thread来实现多线程的实例对象");
}
}
/**
* Created by Admin on 2019/12/4.
* 通过实现Runnable来实现多线程的类
*/
public class ThreadB implements Runnable{
public void run(){
System.out.println("我是一个通过implements Runnable来实现多线程的实例对象");
}
}
测试类:
public class ThreadTest {
public static void main(String[] args) {
//通过继承Thread类来实现多线程的类A,可以直接new对象执行
ThreadA a = new ThreadA();
//通过实现Runnable接口来实现多线程的类B,需要再new Thread(),然后把B的实例封装到Thread中才能执行
ThreadB b = new ThreadB();
Thread thread = new Thread(b);
//我们可以通过setPriority来设置线程优先级,0~10(由低到高)
a.setPriority(0);
thread.setPriority(10);
a.start();
thread.start();
}
输出结果:
我是一个通过implements Runnable来实现多线程的实例对象
我是一个通过extends Thread来实现多线程的实例对象
进程是程序执行的最小资源分配单元,每个进程之间的内存空间是独立的,但是同一个进程的不同线程之间却是共享内存资源(方法区和堆内存,栈内存每个线程是相互独立的)。
所以说,所谓的保证线程安全,指的就是同一进程下起了多个线程,如何保证多个线程对内存资源的操作不会同时修改一个共享数据。
加了同步锁的代码块,同一时间只允许同一进程的一个线程使用。
测试Demo如下:
/**
* 通过继承Thread来实现多线程的类
*/
public class ThreadA extends Thread{
//用于测试的静态共享变量
private static Integer count = 10;
public void run(){
count--;
System.out.println("我是一个通过extends Thread来实现多线程的实例对象,当前count为:"+count);
}
}
测试类:
/**
* 多线程情况下的测试类
*/
public class SyncTest {
public static void main(String[] args) {
ThreadA a1 = new ThreadA();
ThreadA a2 = new ThreadA();
ThreadA a3 = new ThreadA();
a1.start();
a2.start();
a3.start();
}
}
运行结果如下,是有问题的,问题原因是有两个线程同时操作了共享变量count字段:
我是一个通过extends Thread来实现多线程的实例对象,当前count为:8
我是一个通过extends Thread来实现多线程的实例对象,当前count为:8
我是一个通过extends Thread来实现多线程的实例对象,当前count为:7
这就是多线程环境下,对共享资源操作可能存在线程安全的问题。
为了解决这个问题,我们给ThreadA的run方法加上synchronized关键字:
/**
* 通过继承Thread来实现多线程的类
*/
public class ThreadA extends Thread{
//用于测试的共享变量
private static Integer intCount = 10;
public synchronized void run(){
intCount--;
System.out.println("我是一个通过extends Thread来实现多线程的实例对象,当前count为:"+intCount);
}
}
这个时候我们再执行SyncTest,结果如图:
我是一个通过extends Thread来实现多线程的实例对象,当前count为:9
我是一个通过extends Thread来实现多线程的实例对象,当前count为:8
我是一个通过extends Thread来实现多线程的实例对象,当前count为:7
或者我们可以通过ReentrantLock只给对共享变量有操作的代码加锁:
import java.util.concurrent.locks.ReentrantLock;
/**
* 通过继承Thread来实现多线程的类
*/
public class ThreadA extends Thread{
//用于测试的共享变量
private static Integer count = 10;
private static ReentrantLock lock = new ReentrantLock();
public void run(){
lock.lock();
count--;
System.out.println("我是一个通过extends Thread来实现多线程的实例对象,当前count为:"+count);
lock.unlock();
}
}
这样也是线程安全的:
我是一个通过extends Thread来实现多线程的实例对象,当前count为:9
我是一个通过extends Thread来实现多线程的实例对象,当前count为:8
我是一个通过extends Thread来实现多线程的实例对象,当前count为:7