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);
}
}
}
2.实现Runnable接口,覆盖run()方法
public class RunnableImpl implements Runnable {
@Override
public void run() {
System.out.println(Thread.currentThread().getName()+"传统");
}
}
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();
}
}
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();
}
}
存在一票多售和无效票,需要解决线程安全问题
在可能出现线程问题的代码上添加同步锁,保证锁为同一把就完了;新创建一个对象,或者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--;
}
}
}
}
}
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--;
}
}
}
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--;
}
}
}
}
}
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--;
}
}
}
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();
}
}
}
总结:这两种基本的创建线程的方式是使用场景而定,特别是使用线程池的时候,runnable作为参数传递。当然线程的状态,start()和run()的区别,其他的线程实现方式,并包......