并发和并行
并行:同时执行
并发:交替执行
进程和线程
进程:正在执行(main)
线程:main->(多个程序)
多线程的实现方式(3种)
1.继承Thread
package Thread;
//定义一个类MyThread继承Thread类
public class MyThread extends Thread{
//在MyThread类中重写run()方法
public void run() {
for(int i = 0;i<100;i++) {
System.out.println(i);
}
}
}
package Thread;
public class Demo {
public static void main(String[] args) {
//创建MyThread类的对象
MyThread t1 = new MyThread();
MyThread t2 = new MyThread();
//启动线程
t1.start();
t2.start();
}
}
2.实现Runnable接口
package Runnable
//定义一个类MyRunnable实现Runnable接口
public class MyRunnable implements Runnable{
//重写MyRunnable类中重写run()方法
@Override
public void run() {
for(int i = 0;i<100;i++) {
System.out.println(i);
}
}
}
package Runnable;
public class Demo {
public static void main(String[] args) {
//创建MyRunnable类的对象
MyRunnable mr1 = new MyRunnable();
MyRunnable mr2 = new MyRunnable();
//创建Thread类的对象,把MyRunnable对象作为构造方法的参数
Thread t1 = new Thread(mr1);
Thread t2 = new Thread(mr2);
//启动线程
t1.start();
t2.start();
}
}
3.实现callable接口
package Callable;
import java.util.concurrent.Callable;
public class MyCallable implements Callable<String>{
public String call() throws Exception {
for(int i = 0;i<100;i++) {
System.out.println(i);
}
return "答应";
}
}
package Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;
import java.util.concurrent.FutureTask;
public class Demo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
MyCallable mc1 = new MyCallable();
MyCallable mc2 = new MyCallable();
FutureTask<String> ft1 = new FutureTask(mc1);
FutureTask<String> ft2 = new FutureTask(mc2);
Thread t1 = new Thread(ft1);
Thread t2 = new Thread(ft2);
t1.start();
t2.start();
String s = ft1.get();
System.out.println(s);
}
}
线程类的常见方法
1.Thread方法-设置获取名字
t1.setName("aa");
2.Thread方法-获得线程对象
Thread.currentThread();//返回当前正在执行线程的对象引用
3.Thread方法-sleep
Thread.sleep(100);//100us
4.Thread方法-守护线程
daemonThread.setDaemon(true);
5.Thread方法-线程的优先级(3-10,5为默认值)
thread.setPriority(10)
6.Thread方法-线程的生命周期
线程的安全问题
同步代码块
同步方法
package MyRunnable;
public class MyRunnable implements Runnable{
private static int ticketCount = 100;
@Override
public void run() {
// TODO Auto-generated method stub
while(true) {
if("窗口一".equals(Thread.currentThread().getName())) {
//同步方法
boolean result = synchronizedMthod();
if(result) {
break;
}
}
if("窗口二".equals(Thread.currentThread().getName())) {
//同步代码块
synchronized (MyRunnable.class) {
if(ticketCount == 0) {
break;
}else {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ticketCount--;
System.out.println(Thread.currentThread().getName() + "卖掉了第" + ticketCount + "张票");
}
}
}
}
}
private static synchronized boolean synchronizedMthod() {
// TODO Auto-generated method stub
if(ticketCount == 0) {
return true;
} else {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
ticketCount--;
System.out.println(Thread.currentThread().getName() + "卖掉了第" + ticketCount + "张票");
}
return false;
}
}
死锁:
避免锁嵌套,避免死锁。
消费者生产者
生产者消费者分析
生产者步骤:
- 判断桌子上是否有汉堡包 如果有就等待,如果没有才生产
- 把汉堡包放在桌子上
- 叫醒等待的消费者开吃
消费者步骤:
- 判断桌子上是否有汉堡包
- 如果没有就等待
- 如果有就开吃
- 吃完之后,桌子上汉堡包就没有了,叫醒等待的生产者继续生产
- 汉堡包总数量减一
桌子:
定义一个标记
true 就表示桌子上有汉堡包的,此时允许吃货执行
false就表示桌子上没有汉堡包的,此时允许厨师执行
public static boolean flag = false;
套路:
- while(true)死循环
- synchronized锁, 锁对象要唯一
- 判断,共享数据是否结束,结束
- 判断,共享时间是否结束,没有结束