一.线程的创建
1.继承Thread
public class MyThread extends Thread{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"......run called......");
}
public static void main(String[] args) {
MyThread t0 = new MyThread();
MyThread t1 = new MyThread();
t0.start();
t1.start();
System.out.println(Thread.currentThread().getName()+"......main called......");
}
}
2.实现Runnable接口
当某一个类由父类时,无法继承Thread类,可通过实现Runnable接口来实现线程创建
public class MyRunnable implements Runnable{
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"......run called......");
}
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
Thread t0 = new Thread(r);
Thread t1 = new Thread(r);
t0.start();
t1.start();
System.out.println(Thread.currentThread().getName()+"......main called......");
}
}
3.实现细节
public class MyThread {
private Runnable r;
public MyThread(Runnable r) {
this.r = r;
}
public void run(){
}
public void start(){
if(r!=null)
this.run();
}
}
4.Thread和Runnable实现创建线程的区别
- Runnable可避免子类继承Thread类中除run和start以外的方法
- Runnable可避免java单继承的缺陷
- Runnable有共享数据
二.线程安全
1.使用Runnable实现卖票(当线程任务执行很快,要想模拟出2个程序同时执行的效果,使用循坏让程序一直执行)
public class MyRunnable implements Runnable{
private int ticketNo = 100;
@Override
public void run() {
while(true) {
if(ticketNo>0) {
try {
sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName() + "卖出了票号为"+ticketNo+"的票");
ticketNo--;
}
}
}
public static void main(String[] args) {
MyRunnable r = new MyRunnable();
Thread t0 = new Thread(r);
Thread t1 = new Thread(r);
Thread t2 = new Thread(r);
Thread t3 = new Thread(r);
t0.start();
t1.start();
t2.start();
t3.start(); }
}
分析出现0,-1,-2以及4个9的原因。
2.线程安全产生的原因
- 多个线程有共享数据
- 操作共享数据的代码有多份