线程/线程池总结一、线程自定义的线程创建代码:方法一: 新建一个类继承Thread,在里面重写run方法,run()方法里面写该线程需要执行的任务. 在需要实现多线程时创建该线程类的对象,调用start()方法.
import org.junit.Test;
//定义一个自定义线程,重写run()方法
class MyThread extends Thread {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("线程" + Thread.currentThread().getName() + "执行了..." + i);
}
}
}
public class ThreadDemo {
//测试多线程
@Test
public void method01() {
MyThread myThread = new MyThread();
myThread.start();
for (int i = 0; i < 100; i++) {
System.out.println("线程" + Thread.currentThread().getName() + "执行了..." + i);
}
}
}方法二: 使用匿名内部类,创建一个Runnable接口的匿名实现对象,重写里面的run方法. 然后使用Thread类的构造方法 Thread(Runnable runnable,String name)新建一个线程对象,再使用这个对象调用start()方法创建多线程
@Test
public void method02() {
for (int i = 0; i < 100; i++) {
System.out.println("线程" + Thread.currentThread().getName() + "执行了..." + i);
}
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("线程" + Thread.currentThread().getName() + "执行了..." + i);
}
}
}).start();
}二、线程安全线程安全:如果线程不安全,多个线程对同一个变量同时进行操作时,会产生延时或者操作多次的现象; 解决方案:使用同步锁或者lock()方法保证线程安全 同步锁:实现类: class Sales implements Runnable {
int totals = 1000;
Object object = new Object();
@Override
public void run() {
while (true) {
synchronized (object) {
if (totals > 0) {
System.out.println("窗口" + Thread.currentThread().getName() + "正在卖倒数第" + totals + "张票");
totals--;
} else {
break;
}
}
}
}
}测试方法 //测试同步锁(Test插件有问题,会执行不完,放到main()方法就没问题)
@Test
public void method03() {
Sales sales = new Sales();
Thread s1 = new Thread(sales, "ss1");
Thread s2 = new Thread(sales, "ss2");
Thread s3 = new Thread(sales, "ss3");
Thread s4 = new Thread(sales, "ss4");
s1.start();
s2.start();
s3.start();
s4.start();
}Lock类的lock方法解决线程安全:Runnable实现类: class Sales02 implements Runnable {
private int totals = 1000;
Lock lock = new ReentrantLock();
@Override
public void run() {
while (true) {
lock.lock();
if (totals > 0) {
System.out.println("窗口" + Thread.currentThread().getName() + "正在卖倒数第" + totals + "张票");
totals--;
} else {
break;
}
lock.unlock();
}
}
}测试方法 //测试Lock类对象解决线程安全(Test插件有问题,会执行不完,放到main()方法就没问题)
@Test
public void method04() {
Sales02 sales = new Sales02();
Thread s1 = new Thread(sales, "ss1");
Thread s2 = new Thread(sales, "ss2");
Thread s3 = new Thread(sales, "ss3");
Thread s4 = new Thread(sales, "ss4");
s1.start();
s2.start();
s3.start();
s4.start();
}
}
线程间的通信问题消费者生产者案例: 包子铺线程做出包子,做完之后端上来,告诉客人可以吃. 客人吃完,告诉包子铺吃完了,让包子铺进行生产包子 包子类代码 class BaoZi {
private String pi;
private String xian;
int situation = 0;
public String getPi() {
return pi;
}
public void setPi(String pi) {
this.pi = pi;
}
public String getXian() {
return xian;
}
public void setXian(String xian) {
this.xian = xian;
}
public BaoZi(String pi, String xian) {
this.pi = pi;
this.xian = xian;
}
}包子铺线程类代码 //线程间的通信.包子铺类
class BaoZiPu extends Thread {
private BaoZi bz;
public BaoZiPu(BaoZi bz) {
this.bz = bz;
}
@Override
public void run() {
while (true) {
try {
synchronized (bz) {
bz.wait(3000);
if (bz.situation == 1) {
bz.wait();
}
System.out.println("包子做好了,来,请慢用...");
bz.situation = 1;
bz.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}客人线程类代码 //线程间的通信.顾客类
class Customer extends Thread {
BaoZi bz;
public Customer(BaoZi bz) {
this.bz = bz;
}
@Override
public void run() {
while (true) {
try {
synchronized (bz) {
bz.wait(3000);
if (bz.situation == 0) {
System.out.println("没包子了,快点做");
bz.wait();
}
System.out.println("包子上来了,我赶紧趁热吃.");
bz.situation = 0;
System.out.println("吃完了.");
bz.notify();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
测试类 public static void main(String[] args) {
BaoZi bz = new BaoZi("冰皮", "五仁");
new Customer(bz).start();
new BaoZiPu(bz).start();
}
三、线程池线程池使用 Executors中 的静态方法 newFixedThreadPool(int i) 方法创建,i为线程池中线程的数量. 把需要执行的任务写到一个Runnable实现类对象中,或者封装在一个匿名内部类或Lambda表达是中,调用线程池对象的submit方法把任务提交到线程池中执行. 代码: ExecutorService service = Executors.newFixedThreadPool(5);
service.submit(() -> {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() +"哈哈哈哈哈" + i);
}
});
service.submit(() -> {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() +"哈哈哈哈哈" + i);
}
});
service.submit(() -> {
for (int i = 0; i < 100; i++) {
System.out.println( Thread.currentThread().getName() +"哈哈哈哈哈" + i);
}
});
service.submit(() -> {
for (int i = 0; i < 100; i++) {
System.out.println(Thread.currentThread().getName() +"哈哈哈哈哈" + i);
}
});
|