在Java线程中,有以下三种方式可以实现线程的创建。
- 通过继承Thread类,调用Thread的start方法实现线程的创建
- 实现Runnable接口
- 实现Callable接口
继承Thread可以实现线程的创建,但当我们需要继承其他父类的时候,这时候便可以通过实现Runnable或者Callable接口,Callable与Runnable的区别在于Callable有返回值,可以通过返回值判断线程创建是否成功。当需要通过返回值的时候便可以选择实现Callable接口,选择Callable运行方式,需要FutureTask类的支持,用于接收返回的结果。
继承Thread接口:
public class ExtendThread extends Thread{
private int i;
@Override
public void run(){
//当前线程
System.out.println("线程:"+getName());
for(i=0;i<5;i++){
System.out.println(getName()+":"+i);
try{
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public static void main(String[] args){
//创建两个线程
new ExtendThread().start();
new ExtendThread().start();
}
}
实现Runnable接口:
public class ImpleThread implements Runnable{
private int i;
@Override
public void run() {
System.out.println("线程:"+Thread.currentThread().getName());
for(i=0;i<5;i++){
System.out.println(Thread.currentThread().getName()+":"+i);
try{
Thread.sleep(1000);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
public static void main(String[] args){
ImpleThread thread = new ImpleThread();
new Thread(thread).start();
new Thread(thread).start();
}
}
实现Callable接口:
public class CallableThread implements Callable{
@Override
public Boolean call() throws Exception {
System.out.println("线程:"+Thread.currentThread().getName());
return true;
}
/**
* FutureTask可以准确地知道线程什么时候执行完成并获得到线程执行完成后返回的结果
*/
public static void main(String[] args){
CallableThread call = new CallableThread();
FutureTask<Boolean> tk = new FutureTask<Boolean>(call);
new Thread(tk).start();
try{
System.out.println(tk.get());
}catch (Exception e){
e.printStackTrace();
}
}
}
但在多线程中,有时候我们会要求线程之间是线程安全的。所谓线程安全,就是当多个线程访问同一类(对象、方法)时,这个类始终能表现出正确的行为,那么这个类便是线程安全的。线程安全是多个线程访问了时采用了加锁机制,当一个线程访问该类的某个数据是进行保护,其他线程只有等到该线程执行完成后才可访问该类。常见的加锁机制:Synchronized。
不加Synchronized:
public class MyThread extends Thread{
private int i=5;
@Override
public void run() {
i--;
System.out.println(this.currentThread().getName()+":"+i);
}
public static void main(String[] args){
MyThread myThread = new MyThread();
new Thread(myThread,"th1").start();
new Thread(myThread,"th2").start();
new Thread(myThread,"th3").start();
new Thread(myThread,"th4").start();
new Thread(myThread,"th5").start();
}
}
运行结果:
加Synchronized:
public class MyThread extends Thread{
private int i=5;
@Override
public synchronized void run() {
i--;
System.out.println(this.currentThread().getName()+":"+i);
}
public static void main(String[] args){
MyThread myThread = new MyThread();
new Thread(myThread,"th1").start();
new Thread(myThread,"th2").start();
new Thread(myThread,"th3").start();
new Thread(myThread,"th4").start();
new Thread(myThread,"th5").start();
}
}
运行结果: