线程基本使用

1.继承Thread,覆盖run()方法

public class ThreadDemo1 extends Thread{
    @Override
    public void run() {
        for (int i = 0; i < 20; i++) {
          /*  System.out.println("run"+i);
            Thread thread = Thread.currentThread();
            System.out.println(thread);
            String name = thread.getName();
            System.out.println(name);*/
            System.out.println(Thread.currentThread().getName()+"===>"+i);
        }

    }
}

public class MainTest {
    public static void main(String[] args) {
        ThreadDemo1 threadDemo1 = new ThreadDemo1();
        ThreadDemo1 threadDemo11 = new ThreadDemo1();
        threadDemo1.start();
        threadDemo11.start();
        for (int i = 0; i < 20; i++) {
            System.out.println("main"+i);
        }
    }
}
View Code

2.实现Runnable接口,覆盖run()方法

public class RunnableImpl implements Runnable {
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"传统");
    }
}
View Code
public class TestDemo {
    public static void main(String[] args) {
//        传统方式
        RunnableImpl runnable = new RunnableImpl();
        Thread t1 = new Thread(runnable);
        t1.start();
//        匿名内部类
        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "匿名内部类");
            }
        };
//        匿名内部类的简化
        new Thread(runnable1).start();
        new Thread(new Runnable() {
            @Override
            public void run() {
                System.out.println(Thread.currentThread().getName() + "匿名内部类简化");
            }
        }).start();
//使用lambda表达式
        new Thread(() ->{
                System.out.println(Thread.currentThread().getName()+"lambda表达式");
            }
        ).start();
    }
}
View Code
3.线程案例
public class RunnableImpl implements Runnable {
    private int ticket=100;
    @Override
    public void run() {
        while (true){
            if (ticket>0){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
                ticket--;
            }
        }

    }
}

public class TicketDemo {
    public static void main(String[] args) {
        RunnableImpl runnable = new RunnableImpl();
        Thread t1 = new Thread(runnable);
        Thread t2 = new Thread(runnable);
        Thread t3 = new Thread(runnable);
        t1.start();
        t2.start();
        t3.start();
    }
}
View Code

存在一票多售和无效票,需要解决线程安全问题

在可能出现线程问题的代码上添加同步锁,保证锁为同一把就完了;新创建一个对象,或者this当前类,或者同步代码块,同步方法;静态方法使用静态变量也有可能出现线程问题,还是得使用同步机制。

public class RunnableImpl implements Runnable {
    private int ticket=100;
    Object object=new Object();
    @Override
    public void run() {
        while (true){
          synchronized (object){
              if (ticket>0){
                  try {
                      Thread.sleep(10);
                  } catch (InterruptedException e) {
                      e.printStackTrace();
                  }
                  System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
                  ticket--;
              }
          }
        }

    }
}
View Code
public class RunnableImpl implements Runnable {
    private int ticket=100;
    @Override
    public void run() {
        while (true){
            payTicket();

        }

    }
    public synchronized void payTicket(){
        if (ticket>0){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
            ticket--;
        }
    }
}
View Code
public class RunnableImpl implements Runnable {
    private int ticket=100;
    @Override
    public void run() {
        while (true){
           synchronized (this){
               if (ticket>0){
                   try {
                       Thread.sleep(10);
                   } catch (InterruptedException e) {
                       e.printStackTrace();
                   }
                   System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
                   ticket--;
               }
           }
        }

    }
}
View Code
public class RunnableImpl implements Runnable {
    private static int ticket=100;
    @Override
    public void run() {
        while (true){
            payTicket();

        }

    }
    public static synchronized void payTicket(){
        if (ticket>0){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
            ticket--;
        }
    }
}
View Code
public class RunnableImpl implements Runnable {
    private int ticket=100;
    Lock lock=new ReentrantLock();
    @Override
    public void run() {
        while (true){
            lock.lock();
            if (ticket>0){
                try {
                    Thread.sleep(10);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                System.out.println(Thread.currentThread().getName()+"正在卖第"+ticket+"张票");
                ticket--;
            }
            lock.unlock();
        }

    }
}
View Code

 总结:这两种基本的创建线程的方式是使用场景而定,特别是使用线程池的时候,runnable作为参数传递。当然线程的状态,start()和run()的区别,其他的线程实现方式,并包......

原文地址:https://www.cnblogs.com/shun998/p/12551687.html