Java笔记-多线程
进程:执行程序的一次执行过程
线程:如果开辟了多个线程,现成的运行由调度器安排调度。Java有main线程和gc线程
同一份资源,会有资源 抢夺的问题,需要并发控制
CPU调度线程,人为不可干预 ,线程不一定立即执行
创建线程方式:
//方式一:
public class TestThread extends Thread{//继承Thread类
@Override
public void run() {//重写run方法
System.out.println("执行run");
}
public static void main(String[] args) {
TestThread testThread = new TestThread();
testThread.start();//调用start()方法启动线程
}
}
//方式二:
/*runnable是一个接口,Thread也继承了Runnable接口
此种方法,也实现了runnable借口,
new Thread(对象).start();是静态代理
代理和真实对象同时实现一个接口,代理可以做很多事情,start(),真实对象只需要专注做自己的(重写run方法)
*/
public class TestRunnable implements Runnable{//实现Runnable接口
@Override
public void run() {//实现run 方法
System.out.println("执行run方法");
}
public static void main(String[] args) {
TestRunnable testRunnable = new TestRunnable();
new Thread(testRunnable).start(); //创建Thread对象,启动start方法
}
}
//方式三:
new Thread(){ //在方法体中开启线程
@Override
public void run() { //重写run 方法
System.out.println("执行run");
}
}.start
//方式四:
new Thread(()-> System.out.println("线程")).start();
public class TestRunnable implements Runnable{
private int tickNum = 10;
@Override
public void run() {
while(true){
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(tickNum <=0){
break;
}
System.out.println(Thread.currentThread().getName() + "=====>拿到了第" + tickNum-- +"张票");
}
}
public static void main(String[] args) {
TestRunnable testRunnable = new TestRunnable();
new Thread(testRunnable,"小明").start();
new Thread(testRunnable,"老师").start();
new Thread(testRunnable,"黄牛").start();
}
}
执行结果
线程的五大状态
线程礼让
Yield():正在执行的线程暂停,但不阻塞;从运行状态转换为就绪状态;CPU重新调度,礼让不一定成功
线程插队
Join():此线程执行完之后,其他线程待会开始执行。
线程同步
并发:多个线程访问同一个对象。
synchronized加锁
synchronized可以锁一个方法,或者锁块
synchronized(共享资源){//锁的对象时变化的量,需要增删改查的量
}
死锁
多线程对象共享一些资源,都在等着对方资源释放就会造成死锁。
ReenTrantLock 可以加锁解锁
public class implements Runnable{
private final static ReenTrantLock lock = new ReenTrantLock();
@Override
public void run() {
try{
lock.lock();
for(int i = 1 ; i <= 100;i ++){
System.out.println(Thread.currentThread().getName() + "=====跑了" + i + "步");
}
}finally{
lock.unlock();
}
}
}
Lock锁和Synchronized区别
Lock是显示锁(手动开关)synchronized是隐式锁
Lock只有代码块锁,syn有代码块和方法锁
线程池
ExecutorService和Executors
不需要频繁的创建线程,而是在线程池中随取随用
//线程池
public class TestPool {
public static void main(String[] args) {
ExecutorService service = Executors.newFixedThreadPool(10);
service.execute(new myThread());
service.execute(new myThread());
service.execute(new myThread());
service.shutdown();
}
}
class myThread implements Runnable{
@Override
public void run() {
for (int i = 0 ; i< 3 ; i++){
System.out.println(Thread.currentThread().getName()+i);
}
}
}
龟兔赛跑
//龟兔赛跑
public class TestRunnable2 implements Runnable{
private static String winner;
@Override
public void run() {
for(int i = 1 ; i <= 100;i ++){
// if(Thread.currentThread().getName().equals("兔子")){
// try {
// Thread.sleep(10);
// } catch (InterruptedException e) {
// e.printStackTrace();
// }
// }
System.out.println(Thread.currentThread().getName() + "=====跑了" + i + "步");
if(isGameOver(i)){
System.out.println(winner + "赢了");
break;
}
}
}
public boolean isGameOver(int step){
boolean flag = false;
if (winner != null){
flag = true;
}
if(step == 100){
winner = Thread.currentThread().getName();
flag = true;
}
return flag;
}
public static void main(String[] args) {
TestRunnable2 test = new TestRunnable2();
new Thread(test,"兔子").start();
new Thread(test,"乌龟").start();
}
}