| |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
-> Java知识库 -> java中的多线程:线程使用,人生转折! -> 正文阅读 |
|
[Java知识库]java中的多线程:线程使用,人生转折! |
Thread: Thread thread = new Thread() { @Override public void run() { System.out.println(“Thread started!”); } }; thread.start(); 复制代码 Thread类的几个常用的方法:
Runnable:
@FunctionalInterface public interface Runnable { public abstract void run(); } 复制代码 Runnable不利于线程重用管理 Runnable runnable = new Runnable() { @Override public void run() { System.out.println(“Thread with Runnable started!”); } }; Thread thread = new Thread(runnable); thread.start(); 复制代码 ThreadFactory: ThreadFactory factory = new ThreadFactory() { int count = 0; @Override public Thread newThread(Runnable r) { count ++; return new Thread(r, “Thread-” + count); } }; Runnable runnable = new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + “started!”); } }; Thread thread = factory.newThread(runnable); thread.start(); Thread thread1 = factory.newThread(runnable); thread1.start(); 复制代码 Executor线程池: Executor线程池(最为推荐): Runnable runnable = new Runnable() { @Override public void run() { System.out.println(“Thread with Runnable started!”); } }; Executor executor = Executors.newCachedThreadPool(); executor.execute(runnable); executor.execute(runnable); executor.execute(runnable); 复制代码 Callable 和 Future:
@FunctionalInterface public interface Callable { V call() throws Exception; } 复制代码 Callable和Future一般成对出现, Callable callable = new Callable() { @Override public String call() { try { Thread.sleep(1500); } catch (InterruptedException e) { e.printStackTrace(); } return “Done!”; } }; ExecutorService executor = Executors.newCachedThreadPool(); Future future = executor.submit(callable); try { String result = future.get(); System.out.println("result: " + result); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); } 复制代码 线程安全和线程同步 ========= 线程安全:指函数在多线程环境中被调用时,能够正确地处理多个线程之间的全局变量,使得功能正确完成。 线程同步:即当有一个线程在对内存进行操作时,其他线程都不可以对这个内存地址进行操作。 线程同步不等于线程安全,现在很多人误解了这一点而喜欢将他们混为一谈。现实是,当我询问面试者何为线程同步时,很多人回答的都是线程安全。 线程同步是实现线程安全的一种手段,你当然也可以用其他的方式达到线程安全。 线程安全的本质问题是资源问题: 当一个共享资源被一个线程读操作时,该资源不能被其他线程任意写; 当一个共享资源被一个线程写操作时,该资源不能被其他线程任意读写; 下面介绍java中实现线程安全的几种方式: synchronized synchronized以同步方式保证了方法内部或代码块内部资源(数据)的互斥访问,保证了线程之间对监视资源的数据同步. private synchronized void count(int newValue) { x = newValue; System.out.println("x= " + x); } 复制代码 另一种写法: private void count(int newValue) { synchronized (this) { x = newValue; System.out.println("x= " + x); } } 复制代码 volatile volatile关键字修饰的变量具有原子性和同步性,相当于实现了对单?字段的线程间互斥访问。 volatile关键字能够保证内存的可见性,如果用volatile关键字声明了一个变量,在一个线程里面改变了这个变量的值,那其它线程是立马可见更改后的值的。 volatile可以看做是简化版的 synchronized. volatile 只对基本类型 (byte、char、short、int、long、float、double、boolean)的赋值操作和对象的引?赋值操作有效。 java.util.concurrent.atomic: AtomicInteger、AtomicBoolean 等类,作?和 volatile 基本?致,可以看做是 volatile修饰的Integer、Boolean等类。 Lock / ReentrantReadWriteLock Lock同样是加锁机制,但使??式更灵活,同时也更麻烦: Lock lock = new ReentrantLock(); … lock.lock(); try { x++; } finally { lock.unlock(); } 复制代码 Synchronized存在的一个性能问题就是读与读之间互斥,所以我们?般并不会只是使? ReentrantReadWriteLock lock = new ReentrantReadWriteLock(); Lock readLock = lock.readLock(); Lock writeLock = lock.writeLock(); private int x = 0; private void writeOperate () { writeLock.lock(); try { x++; } finally { writeLock.unlock(); } } private void readOperate ( int time){ readLock.lock(); try { System.out.println(); } finally { readLock.unlock(); } } 复制代码 读取锁是共享的,因而上述代码中,有线程写操作时,其他线程不可写,不可读;该线程读操作时,其他线程不可写,但可读。 线程间通信/交互 ======== 线程有自己的私有空间,但当我多个线程之间相互协作的时候,就需要进行线程间通信方,本节将介绍Java线程之间的几种通信原理。 锁与同步 这种方式主要是对全局变量加锁,即用 这种方式可详见上一节线程同步中的例子。 等待/通知机制 基于“锁”的方式需要线程不断去尝试获得锁,这会耗费服务器资源。 Java多线程的等待/通知机制是基于
notify()方法会随机叫醒一个正在等待的线程,而notifyAll()会叫醒所有正在等待的线程,被唤醒的线程重新在就绪队列中按照一定算法最终再次被处理机获得并进行处理,而不是立马重新获得处理机。 public class mythread { private static Object lock = new Object(); static class ThreadA implements Runnable { @Override public void run() { synchronized (lock) { for (int i = 0; i < 5; i++) { try { System.out.println("ThreadA: " + i); lock.notify(); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } lock.notify(); } } } static class ThreadB implements Runnable { @Override public void run() { synchronized (lock) { for (int i = 0; i < 5; i++) { try { System.out.println("ThreadB: " + i); lock.notify(); lock.wait(); } catch (InterruptedException e) { e.printStackTrace(); } } lock.notify(); } } } public static void main(String[] args) { new Thread(new ThreadA()).start(); try { Thread.sleep(10000); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(new ThreadB()).start(); } } 复制代码 join方法
当主线程创建并启动了耗时子线程,而主线程早于子线程结束之前结束时,就可以用join方法等子线程执行完毕后,从而让主线程获得子线程中的处理完的某个数据。 join()方法及其重载方法底层都是利用了wait(long)这个方法。 public class mythread { static class ThreadA implements Runnable { @Override public void run() { try { System.out.println(“子线程睡一秒”); Thread.sleep(1000); System.out.println(“子线程睡完了一秒”); } catch (InterruptedException e) { e.printStackTrace(); } catch (InterruptedException e) { e.printStackTrace(); } new Thread(new ThreadB()).start(); } } 复制代码 join方法
当主线程创建并启动了耗时子线程,而主线程早于子线程结束之前结束时,就可以用join方法等子线程执行完毕后,从而让主线程获得子线程中的处理完的某个数据。 join()方法及其重载方法底层都是利用了wait(long)这个方法。 public class mythread { static class ThreadA implements Runnable { @Override public void run() { try { System.out.println(“子线程睡一秒”); Thread.sleep(1000); System.out.println(“子线程睡完了一秒”); } catch (InterruptedException e) { e.printStackTrace(); |
|
|
上一篇文章 下一篇文章 查看所有文章 |
|
开发:
C++知识库
Java知识库
JavaScript
Python
PHP知识库
人工智能
区块链
大数据
移动开发
嵌入式
开发工具
数据结构与算法
开发测试
游戏开发
网络协议
系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程 数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁 |
360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 | -2024/11/24 0:20:48- |
|
网站联系: qq:121756557 email:121756557@qq.com IT数码 |