创建线程的几种方法
继承Thread类创建线程
java
public class Creation {
public static void main(String[] args) {
MyThread thread = new MyThread();
thread.start();
}
}
class MyThread extends Thread {
@Override
public void run() {
System.out.println("running...");
}
}
实现Runnable接口创建线程
java
public class Creation {
public static void main(String[] args) {
MyThread myThread = new MyThread();
Thread thread = new Thread(myThread);
thread.start();
}
}
class MyThread implements Runnable {
@Override
public void run() {
System.out.println("running...");
}
}
Thrad和Runnable的关系
Thread实现了Runable接口。
java
public class Thread implements Runnable {
private Runnable target;
public Thread(Runnable target) {
init(null, target, "Thread-" + nextThreadNum(), 0);
}
@Override
public void run() {
if (target != null) {
// 1.要么重写 Runnable 的 run 方法。
// 2.要么传入 Runnable 的实现类,调用其 run 方法。
target.run();
}
}
}
Thread与Runable创建线程区别
Runnable可理解为资源,Thread理解为处理资源的线程。
1、继承Thread类的方式,new了三个Thread,实际上是有300张票。
2、实现Runnable接口的方式,new了三个Thread,实际上是有100张票。
3、也就是说实现Runnable接口的线程中,成员属性是所有线程共有的。但是继承Thread类的线程中,成员属性是各个线程独有的,其它线程看不到,除非采用static的方式才能使各个线程都能看到。
4、就像上面说的Runnable相当于资源,Thread才是线程。用Runnable创建线程时,new了多个Thread,但是传进去的参数都是同一个Runnable(资源)。用Thread创建线程时,就直接new了多个线程,每个线程都有自己的Runnable(资源)。在Thread源码中就是用target变量(这是一个Runnable类型的变量)来表示这个资源。
5、同时因为这两个的区别,在并发编程中,继承了Thread的子类在进行线程同步时不能将成员变量当做锁,因为多个线程拿到的不是同一把锁,不过用static变量可以解决这个问题。而实现了Runnable接口的类在进行线程同步时没有这个问题。
java
class Window extends Thread{
private int ticket = 100;
@Override
public void run() {
while(true){
if(ticket > 0){
System.out.println(getName() + ":卖票,票号为:" + ticket);
ticket--;
}else{
break;
}
}
}
}
public class WindowTest {
public static void main(String[] args) {
Window t1 = new Window();
Window t2 = new Window();
Window t3 = new Window();
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
java
class Window1 implements Runnable{
private int ticket = 100;
@Override
public void run() {
while(true){
if(ticket > 0){
System.out.println(Thread.currentThread().getName() + ":卖票,票号为:" + ticket);
ticket--;
}else{
break;
}
}
}
}
public class WindowTest1 {
public static void main(String[] args) {
Window1 w = new Window1();
Thread t1 = new Thread(w);
Thread t2 = new Thread(w);
Thread t3 = new Thread(w);
t1.setName("窗口1");
t2.setName("窗口2");
t3.setName("窗口3");
t1.start();
t2.start();
t3.start();
}
}
实现Callable接口创建线程
java
package sort.impl.juc;
import java.util.concurrent.Callable;
import java.util.concurrent.FutureTask;
/**
* @author WanJie
* @since 2023-08-09 11:29
*/
public class Creation {
public static void main(String[] args) {
FutureTask<String> futureTask = new FutureTask<String>(new MyThread());
Thread thread = new Thread(futureTask);
thread.start();
}
}
class MyThread implements Callable {
@Override
public Object call() throws Exception {
System.out.println("running");
return "0K";
}
}