本文共 9033 字,大约阅读时间需要 30 分钟。
程序是指令和数据的有序集合,是静态的概念;进程是程序的一次执行过程,是一个动态的概念,是系统资源分配的单位;线程是CPU调度和执行的单位;
注意:很多多线程是模拟出来的,真正的多线程是指有多个cpu,即多核。
在程序运行时,即使自己没有创建线程,后台也会有多个线程,如主线程,gc线程。
对同一份资源操作时,会存在资源抢夺的问题,需要加入并发控制。
//下载器class WebDownloader { public void download(String url, String name) { try { FileUtils.copyURLToFile(new URL(url) ,new File(name)); } catch (IOException e) { e.printStackTrace(); } }}//实现多线程同步下载图片public class TestThread2 extends Thread{ private String url; private String name; public TestThread2(String url, String name) { this.url = url; this.name = name; } @Override public void run() { WebDownloader downloader = new WebDownloader(); downloader.download(url, name); System.out.println("下载了文件名为:" + name); } public static void main(String[] args) { TestThread2 t1 = new TestThread2("https://pics7.baidu.com/feed/0d338744ebf81a4cbf5a41d981e0105e242da68c.jpeg?token=760f959b12c1adc6be805c125a569b6b", "1.jpg"); TestThread2 t2 = new TestThread2("https://pics3.baidu.com/feed/9358d109b3de9c8231a97ed1ca4fef0d1bd843f2.jpeg?token=766bf62b302cb0d56fb24c4469bb57a2", "2.jpg"); TestThread2 t3 = new TestThread2("https://pics3.baidu.com/feed/314e251f95cad1c8773c1c6ddaf0080ecb3d51cf.jpeg?token=42e2511b4151fcf2d648be6eff246e1d", "3.jpg"); t1.start(); t2.start(); t3.start(); }}
public class TestThrea3 implements Runnable{ public void run() { for (int i = 0; i < 10; i++) { System.out.println("我在看第-" + i + "-行代码"); } } public static void main(String[] args) { TestThrea3 testThrea3 = new TestThrea3(); new Thread(testThrea3).start(); }}
public class TestThread4 implements Runnable{ private Integer ticketNum = 10; public void run() { while (true) { if (ticketNum <= 0) { break; } try { Thread.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketNum-- + "张票"); } } public static void main(String[] args) { TestThread4 ticket = new TestThread4(); new Thread(ticket, "小明").start(); new Thread(ticket, "小红").start(); new Thread(ticket, "黄牛党").start(); }}
发现问题:多个线程操作同一个资源的情况下,线程不安全,数据紊乱。
public class TestLambda1 { public static void main(String[] args) { //匿名内部类 new Thread(new Runnable() { public void run() { System.out.println("这是一个匿名内部类..."); } }).start(); //Lambda表达式 new Thread(() -> { System.out.println("这是一个Lambda表达式..."); }).start(); }}
public class TestStop implements Runnable{ //定义线程中使用的标识 private boolean flag = true @Override public void run() { while (flag) { System.out.println("run...Thread"); } } //对外提供方法改变标识 public void stop() { this.flag = false; }}
//线程不安全的集合public class UnSafeList { public static void main(String[] args) { Listlist = new ArrayList (); for (int i = 0; i < 1000; i++) { new Thread(() -> { list.add(Thread.currentThread().getName()); }).start(); } System.out.println(list.size()); }}
public class SafeList { public static void main(String[] args) { Listlist = new ArrayList (); for (int i = 0; i < 1000; i++) { new Thread(() -> { synchronized (list) { list.add(Thread.currentThread().getName()); } }).start(); } try { Thread.sleep(3_000); } catch (InterruptedException e) { e.printStackTrace(); } System.out.println(list.size()); }}
public void make() throws InterruptedException { if (choice ==0) { synchronized (lipstick) { //获得口红 System.out.println(this.girlName + "获得了口红"); Thread.sleep(1000); synchronized (mirror) { //还想获得镜子 System.out.println(this.girlName + "获得了镜子"); } } } else { synchronized (mirror) { //获得镜子 System.out.println(this.girlName + "获得了镜子"); Thread.sleep(1000); synchronized (lipstick) { //还想获得口红 System.out.println(this.girlName + "获得了口红"); } } } }
private ReentrantLock lock = new ReentrantLock(); public synchronized void run() { while (true) { if (ticketNum <= 0) { break; } lock.lock(); try { Thread.sleep(2000); //sleep不会释放锁对象 System.out.println(Thread.currentThread().getName() + "拿到了第" + ticketNum-- + "张票"); } catch (InterruptedException e) { e.printStackTrace(); } finally { lock.unlock(); } } }
synchronized与Lock的对比
class SynContainer { Chicken[] chickens = new Chicken[10]; //容器 int count = 0; //容器大小 public synchronized void push(Chicken chicken) { //生产者放入产品 if (count == chickens.length) { //容器满了---生产者等待,通知消费者 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } chickens[count] = chicken; //没有满,生产者生产 count++; this.notifyAll(); } public synchronized Chicken pop() { //消费者消费 if (count ==0) { //容器为0,消费者等待,通知生产者 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } count--; //不为空,消费者消费 this.notifyAll(); return chickens[count]; }}
class TV { //共享资源 private String movie; private boolean flag = true; public synchronized void play(String movie) { //生产者生产 if (!flag) { try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("演员表演了:" + movie); this.movie = movie; this.notifyAll(); //通知观众观看 this.flag = !this.flag; } public synchronized void watch() { if (flag) { //还没表演 try { this.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } System.out.println("观众观看了" + movie); this.notifyAll(); //通知观众观看 this.flag = !this.flag; }}
public class TestPool { public static void main(String[] args) { ExecutorService service = Executors.newFixedThreadPool(10); service.execute(new MyTask()); service.execute(new MyTask()); service.shutdown(); }}class MyTask implements Runnable { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "正在运行..."); } }}[] args) { ExecutorService service = Executors.newFixedThreadPool(10); service.execute(new MyTask()); service.execute(new MyTask()); service.shutdown(); }}class MyTask implements Runnable { @Override public void run() { for (int i = 0; i < 5; i++) { System.out.println(Thread.currentThread().getName() + "正在运行..."); } }}
转载地址:http://tiwaz.baihongyu.com/