一:创建线程的两种方式
1.继承Thread类
//继承Thread类实现多线程
//经典案例:火车票购票
class Train extends Thread{
private int tic;
@Override
public void run() {
for(tic=20;tic>0;tic--){
System.out.println(tic);
}
}
}
public class ThreadDemo {
public static void main(String [] args){
new Train().start();
new Train().start();
new Train().start();
}
}
2.实现Runnable接口
//实现Runnable类实现多线程
//经典案例:火车票购票
class Train implements Runnable{
private int tic;
@Override
public void run() {
for(tic=20;tic>0;tic--){
System.out.println(tic);
}
}
}
public class ThreadDemo {
public static void main(String [] args){
Train t1=new Train();
new Thread(t1).start();
new Thread(t1).start();
new Thread(t1).start();
new Thread(t1).start();
}
}
两种方式创建线程的优缺点:用于java中只有单继承,所以当一个类需要继承另一个类时,就只能用实现Runnable 接口的方式。
二:线程的安全性问题
//实现Runnable类实现多线程
//经典案例:火车票购票
class Train implements Runnable{
private int tic;
@Override
public void run() {
for(tic=20;tic>0;tic--){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+"购买了第"+tic+"张票");
}
}
}
public class ThreadDemo {
public static void main(String [] args){
Train t1=new Train();
new Thread(t1,"小明").start();
new Thread(t1,"小王").start();
new Thread(t1,"小张").start();
new Thread(t1,"小李").start();
}
}
从运行结果看出,出现了有人购买第0张票,甚至是负数。
解决方案:
1.将可能出现问题的代码放到Synchronized代码块,Synchronized方法中
//实现Runnable类实现多线程
//经典案例:火车票购票
class Train implements Runnable{
private int tic=200;
@Override
public void run() {
for(int i=0;i<200;i++){
synchronized(this){
if(tic>0){
System.out.println(Thread.currentThread().getName()+"购买了第"+tic+"张票");
tic--;
}
}
}
}
}
public class ThreadDemo {
public static void main(String [] args){
Train t1=new Train();
new Thread(t1,"小明").start();
new Thread(t1,"小王").start();
new Thread(t1,"小张").start();
new Thread(t1,"小李").start();
}
}
//实现Runnable类实现多线程
//经典案例:火车票购票
class Train implements Runnable{
private int tic=200;
@Override
public void run() {
for(int i=0;i<200;i++){
buy();
}
}
synchronized private void buy(){
if(tic>0){
System.out.println(Thread.currentThread().getName()+"购买了第"+tic+"张票");
tic--;
}
}
}
public class ThreadDemo {
public static void main(String [] args){
Train t1=new Train();
new Thread(t1,"小明").start();
new Thread(t1,"小王").start();
new Thread(t1,"小张").start();
new Thread(t1,"小李").start();
}
}
2.Lock类
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
//实现Runnable类实现多线程
//经典案例:火车票购票
class Train implements Runnable{
private int tic=200;
Lock lock=new ReentrantLock();
@Override
public void run() {
for(int i=0;i<200;i++){
lock.lock();
if(tic>0){
System.out.println(Thread.currentThread().getName()+"购买了第"+tic+"张票");
tic--;
}
lock.unlock();
}
}
}
public class ThreadDemo {
public static void main(String [] args){
Train t1=new Train();
new Thread(t1,"小明").start();
new Thread(t1,"小王").start();
new Thread(t1,"小张").start();
new Thread(t1,"小李").start();
}
}