进程与线程
进程:一个正在运行的程序,是系统分配资源的单位
线程:是cup调度和执行的单位
线程图片下载
package thread.file; import org.apache.commons.io.FileUtils; import java.io.File; import java.io.IOException; import java.net.URL; public class jpgDownloaderThread extends Thread{ private String Url; private String name; public jpgDownloaderThread(String Url,String name){ this.Url=Url; this.name=name; } @Override public void run() { new JpgDownloader().download(Url,name); System.out.println(name+"下载完成"); } //https://p.ssl.qhimg.com/dmsmty/148_148_100/t01f6b1cb843eb72a12.png public static void main(String[] args) { jpgDownloaderThread thread1 = new jpgDownloaderThread("https://p.ssl.qhimg.com/dmsmty/148_148_100/t01f6b1cb843eb72a12.png", "1.png"); jpgDownloaderThread thread2 = new jpgDownloaderThread("https://p.ssl.qhimg.com/dmsmty/148_148_100/t01f6b1cb843eb72a12.png", "2.png"); jpgDownloaderThread thread3 = new jpgDownloaderThread("https://p.ssl.qhimg.com/dmsmty/148_148_100/t01f6b1cb843eb72a12.png", "3.png"); thread1.start(); thread2.start(); thread3.start(); System.out.println("主程序运行完成"); } } class JpgDownloader{ public void download(String url,String name){ try { FileUtils.copyURLToFile(new URL(url), new File(name)); } catch (IOException e) { e.printStackTrace(); } } }
运行结果
线程开启不一定立即执行,有cpu调度执行
龟兔赛跑
package thread.race; public class Race implements Runnable { public static String winner; @Override public void run() { for (int i = 1; i <=100; i++) { if(Thread.currentThread().getName().equals("兔子")&&i%10==0){ try { Thread.sleep(1); } catch (InterruptedException e) { e.printStackTrace(); } } boolean b = race(i); if (b){ break; } System.out.println(Thread.currentThread().getName()+"跑了"+i+"步"); } } public boolean race(int step){ if(winner!=null){ return true; } if(step>=100){ winner=Thread.currentThread().getName(); System.out.println("胜利者是:"+winner); return true; } return false; } public static void main(String[] args) { Race race = new Race(); new Thread(race,"兔子").start(); new Thread(race,"乌龟").start(); } }
常用方法
sleep():睡眠
yield():放弃CPU资源,礼让不一定成功
join():相当于线程插队
package thread.method; public class Join implements Runnable { @Override public void run() { for (int i = 0; i < 2; i++) { System.out.println(Thread.currentThread().getName()+i); } } public static void main(String[] args) { Join join = new Join(); Thread thread = new Thread(join, "线程"); thread.start(); for (int i = 0; i < 2; i++) { if(i==1){ try { thread.join();//相当于插队,主线程阻塞 } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("主线程"+i); } } }
setPriority():设置优先级(先设置优先级再启动线程,优先级越高,证明抢cpu机会越大,但不一定最先执行)
package thread.priority; public class Priority { public static void main(String[] args) { SetP setP = new SetP(); Thread thread = new Thread(setP); Thread thread2 = new Thread(setP); Thread thread3 = new Thread(setP); Thread thread4 = new Thread(setP); Thread thread5 = new Thread(setP); thread.setPriority(1); thread.start(); thread2.setPriority(7); thread2.start(); thread3.setPriority(8); thread3.start(); thread4.setPriority(5); thread4.start(); thread5.setPriority(10); thread5.start(); } } class SetP implements Runnable{ @Override public void run() { System.out.println("优先级为:"+Thread.currentThread().getPriority()); } }
setDaemon(ture):默认为false,用户线程
线程同步
两种方式
同步方法:直接加到发生线程安全的方法上
同步块:synchronized(发生线程安全的对象){ 发生线程安全代码块 }
package thread.safe; public class ThreadSafe implements Runnable{ private int i=10; boolean flag=true; @Override public void run() { while (flag){ buy(); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } } //synchronized 表示当前对象this (ThreadSafe) /*public synchronized void buy(){ System.out.println(Thread.currentThread().getName()+"购买了第"+i--+"张票"); if(i<=0){ flag=false; } }*/ //synchronized 表示当前对象this (ThreadSafe) public void buy(){ synchronized(this){ System.out.println(Thread.currentThread().getName()+"购买了第"+i--+"张票"); if(i<=0){ flag=false; } } } public static void main(String[] args) { ThreadSafe threadSafe = new ThreadSafe(); new Thread(threadSafe,"张三").start(); new Thread(threadSafe,"李四").start(); new Thread(threadSafe,"王五").start(); } }
Lock锁
package thread.safe; import java.util.concurrent.locks.ReentrantLock; public class LockSafe implements Runnable { private int i = 10; private final ReentrantLock lock = new ReentrantLock(); @Override public void run() { while (true) { try { lock.lock(); if(i>0){ System.out.println(Thread.currentThread().getName()+"购买了第"+i--+"张票"); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } }else{ break; } } finally { lock.unlock(); } } } public static void main(String[] args) { LockSafe lockSafe = new LockSafe(); new Thread(lockSafe, "张三").start(); new Thread(lockSafe, "李四").start(); new Thread(lockSafe, "王五").start(); } }
线程的五个状态
package thread.state; public class State { public static void main(String[] args) { Thread thread = new Thread(() -> { try { Thread.sleep(100); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println("线程执行完毕"); }); Thread.State state = thread.getState(); System.out.println(state);//new thread.start(); state=thread.getState(); System.out.println(state);//run while(state!=Thread.State.TERMINATED){ try { Thread.sleep(10); } catch (InterruptedException e) { e.printStackTrace(); } state = thread.getState(); System.out.println(state); } } }
线程四种实现方法
继承Thread类
public class ThreadTest { public static void main(String[] args) { System.out.println("main方法开始执行"); new Thread(new Thread1()).start(); System.out.println("main方法执行结束"); } public static class Thread1 extends Thread { @Override public void run() { System.out.println("继承thread类"); } } }
运行结果
实现Runnable接口
public class ThreadTest { public static void main(String[] args) { System.out.println("main方法开始执行"); new Thread(new Thread1()).start(); System.out.println("main方法执行结束"); } public static class Thread1 implements Runnable { @Override public void run() { System.out.println("继承thread类"); } } }
运行结果
实现Callable接口(有返回值)
import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class ThreadTest { public static void main(String[] args) throws ExecutionException, InterruptedException { System.out.println("main方法开始执行"); FutureTask<Integer> futureTask = new FutureTask<>(new Thread1()); new Thread(futureTask).start(); System.out.println(futureTask.get()); System.out.println("main方法执行结束"); } public static class Thread1 implements Callable<Integer> { @Override public Integer call() { System.out.println("继承thread类"); return 1; } } }
运行结果(阻塞等待,等整个线程完成才获取返回值)
线程池(避免大量创建线程造成资源浪费,影响性能)
import java.util.concurrent.*; public class ThreadTest { public static ExecutorService executor = Executors.newFixedThreadPool(10); public static void main(String[] args) throws ExecutionException, InterruptedException { //executor.execute(); 这个方法没返回值 System.out.println("main方法开始执行"); Future<Integer> submit = executor.submit(new Thread1()); System.out.println(submit.get()); System.out.println("main方法执行结束"); executor.shutdown(); } public static class Thread1 implements Callable<Integer> { @Override public Integer call() { System.out.println("继承thread类"); return 1; } } }
运行结果
线程池的七大参数
- 核心线程数
- 最大线程数
- 存活时间
- 时间单位
- 阻塞队列
- 线程工程
- 拒绝策略