实现线程的两种方式:
继承Thread或实现Runnable接口
线程的生命周期:
多个线程操作同一数据的安全用例:
import org.junit.Test;
import java.util.concurrent.CountDownLatch;
//多个线程下对ticket的售卖
public class TestThread {
@Test
public void ssss() {
int threadNum = 4;
//@Test不同于main方法,需要下面的同步工具等待子线程执行完成
//启用同步工具类对子线程计数,为了让主线程启动子线程后,等待子线程完成对应的工作
CountDownLatch countDownLatch = new CountDownLatch(threadNum);
//开启子线程,为了让他们的锁一致,多个线程需要同一个对象
MyTask myTask = new MyTask(countDownLatch);
for (int i = 0; i < threadNum; i++) {
new Thread(myTask).start();
}
try {
countDownLatch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
class MyTask implements Runnable {
private CountDownLatch countDownLatch;
private int ticket = 100;
public MyTask(CountDownLatch countDownLatch) {
this.countDownLatch = countDownLatch;
}
@Override
public void run() {
while (ticket>0){
sale();
try {
Thread.currentThread().sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
countDownLatch.countDown();
}
public void sale() {
synchronized (MyTask.class) {
System.out.println(Thread.currentThread().getName() + "::::::::出售第" + ticket--);
}
}
}