- 浏览: 599534 次
- 性别:
- 来自: 厦门
文章分类
- 全部博客 (669)
- oracle (36)
- java (98)
- spring (48)
- UML (2)
- hibernate (10)
- tomcat (7)
- 高性能 (11)
- mysql (25)
- sql (19)
- web (42)
- 数据库设计 (4)
- Nio (6)
- Netty (8)
- Excel (3)
- File (4)
- AOP (1)
- Jetty (1)
- Log4J (4)
- 链表 (1)
- Spring Junit4 (3)
- Autowired Resource (0)
- Jackson (1)
- Javascript (58)
- Spring Cache (2)
- Spring - CXF (2)
- Spring Inject (2)
- 汉字拼音 (3)
- 代理模式 (3)
- Spring事务 (4)
- ActiveMQ (6)
- XML (3)
- Cglib (2)
- Activiti (15)
- 附件问题 (1)
- javaMail (1)
- Thread (19)
- 算法 (6)
- 正则表达式 (3)
- 国际化 (2)
- Json (3)
- EJB (3)
- Struts2 (1)
- Maven (7)
- Mybatis (7)
- Redis (8)
- DWR (1)
- Lucene (2)
- Linux (73)
- 杂谈 (2)
- CSS (13)
- Linux服务篇 (3)
- Kettle (9)
- android (81)
- protocol (2)
- EasyUI (6)
- nginx (2)
- zookeeper (6)
- Hadoop (41)
- cache (7)
- shiro (3)
- HBase (12)
- Hive (8)
- Spark (15)
- Scala (16)
- YARN (3)
- Kafka (5)
- Sqoop (2)
- Pig (3)
- Vue (6)
- sprint boot (19)
- dubbo (2)
- mongodb (2)
最新评论
synchronized使用起来非常简单,有三种使用模式:
1. 作为修饰符加在方法声明上,synchronized修饰非静态方法时表示锁住了调用该方法的堆对象,修饰静态方法时表示锁住了这个类在方法区中的类对象(记住JAVA中everything is object)。
2.可以用synchronized直接构建代码块。
3.在使用Object.wait()使当前线程进入该Object的阻塞队列时,以及用Object.notify()或Object.notifyAll()唤醒该Object的阻塞队列中一个或所有线程时,必须在外层使用synchronized (Object),这是JAVA中线程同步的最常见做法。之所以在这里要强制使用synchronized代码块,是因为在JAVA语义中,wait有出让Object锁的语义,要想出让锁,前提是要先获得锁,所以要先用synchronized获得锁之后才能调用wait,notify原因类似,另外,我们知道操作系统信号量的增减都是原子性的,而Object.wait()和notify()不具有原子性语义,所以必须用synchronized保证线程安全。
另外,在使用synchronized时有三个原则:
a) sychronized的对象最好选择引用不会变化的对象(例如被标记为final,或初始化后永远不会变),原因显而易见的,虽然synchronized是在对象上加锁,但是它首先要通过引用来定位对象,如果引用会变化,可能带来意想不到的后果,对于需要synchronized不同对象的情况,建议的做法是为每个对象构建一个Object锁来synchronized(不建议对同一个引用反复赋值)。当然将synchronized作为修饰符修饰方法就不会有引用变化的问题,但是这种做法在方法体较大时容易违反第二个原则。
b) 尽可能把synchronized范围缩小,线程互斥是以牺牲并发度为代价的,这点大家都懂。
c) 尽量不要在可变引用上wait()和notify()。
现在需要计算1+2+3+....+30000的和。请采用多线程完成此计算工作,要求如下:
主线程启动三个线程,分别给它们分派以下任务:
线程1:计算1+2+3+...+10000
线程2:计算10001+10002+...+20000
线程3:计算20001+20002+...+30000
等三个线程都完成工作之后,主线程汇总三个工作线程的计算结果,得到最终答案:
1 + 2 + 3 + .... + 30000 = 450015000
使用while true的方式进行阻塞主函数从而使线程继续执行直到线程执行完毕
1. 作为修饰符加在方法声明上,synchronized修饰非静态方法时表示锁住了调用该方法的堆对象,修饰静态方法时表示锁住了这个类在方法区中的类对象(记住JAVA中everything is object)。
2.可以用synchronized直接构建代码块。
3.在使用Object.wait()使当前线程进入该Object的阻塞队列时,以及用Object.notify()或Object.notifyAll()唤醒该Object的阻塞队列中一个或所有线程时,必须在外层使用synchronized (Object),这是JAVA中线程同步的最常见做法。之所以在这里要强制使用synchronized代码块,是因为在JAVA语义中,wait有出让Object锁的语义,要想出让锁,前提是要先获得锁,所以要先用synchronized获得锁之后才能调用wait,notify原因类似,另外,我们知道操作系统信号量的增减都是原子性的,而Object.wait()和notify()不具有原子性语义,所以必须用synchronized保证线程安全。
另外,在使用synchronized时有三个原则:
a) sychronized的对象最好选择引用不会变化的对象(例如被标记为final,或初始化后永远不会变),原因显而易见的,虽然synchronized是在对象上加锁,但是它首先要通过引用来定位对象,如果引用会变化,可能带来意想不到的后果,对于需要synchronized不同对象的情况,建议的做法是为每个对象构建一个Object锁来synchronized(不建议对同一个引用反复赋值)。当然将synchronized作为修饰符修饰方法就不会有引用变化的问题,但是这种做法在方法体较大时容易违反第二个原则。
b) 尽可能把synchronized范围缩小,线程互斥是以牺牲并发度为代价的,这点大家都懂。
c) 尽量不要在可变引用上wait()和notify()。
现在需要计算1+2+3+....+30000的和。请采用多线程完成此计算工作,要求如下:
主线程启动三个线程,分别给它们分派以下任务:
线程1:计算1+2+3+...+10000
线程2:计算10001+10002+...+20000
线程3:计算20001+20002+...+30000
等三个线程都完成工作之后,主线程汇总三个工作线程的计算结果,得到最终答案:
1 + 2 + 3 + .... + 30000 = 450015000
/** * */ package test.SyncAdd; /** * @projectName:zhngdps * @packageName: test.SyncAdd * @ClassName : SyncAddTest * @createBy :Test * @createDate :2014-6-5 上午09:03:35 * @useFor : * */ public class SyncAddTest { private int getAddCount(int begin,int end,String threadName) { TestA test1 = new TestA(begin,end); Thread th1 = new Thread(test1,threadName); th1.start() ; /* * 对线程对象加锁 针对的是同一个类的多个对象的线程 * 使得多线程运行结果可以控制,synchronized用于保护共享数据 */ synchronized (th1) { try { th1.wait(); } catch (InterruptedException e) { e.printStackTrace(); } return test1.getSum() ; } } public static void main(String[] args) { SyncAddTest t = new SyncAddTest(); int sum1 = t.getAddCount(0,10000,"th1"); System.out.println(sum1); int sum2 = t.getAddCount(10001,20000,"th2") ; System.out.println(sum2); int sum3 = t.getAddCount(20001,30000,"th3") ; System.out.println(sum3); int sum = sum1 + sum2 + sum3 ; System.out.println(sum); } }; class TestA implements Runnable { private int begin ; private int end ; private int sum = 0; public TestA(int begin,int end) { this.begin = begin ; this.end = end ; } @Override public void run() { add(); System.out.println(Thread.currentThread().getName()); } private void add() { for(int i=begin;i<=end;i++) { sum += i ; } } public int getSum() { return this.sum ; } };
使用while true的方式进行阻塞主函数从而使线程继续执行直到线程执行完毕
class ThTest implements Runnable { private int start; private int end; private int sum = 0; private boolean isComplete = false; public boolean isComplete() { return isComplete; } public ThTest() { super(); } public ThTest(int start, int end) { this.start = start; this.end = end; } public int getSum() { return this.sum; } @Override public void run() { synchronized (this) { for (int i = start; i <= end; i++) { sum += i; } isComplete = true; } } public static void main(String[] args) { ThTest thTest01 = new ThTest(1, 50000); ThTest thTest02 = new ThTest(50001, 100000); Thread thread01 = new Thread(thTest01); Thread thread02 = new Thread(thTest02); ExecutorService threaPool = Executors.newCachedThreadPool(); threaPool.execute(thread01); threaPool.execute(thread02); while (true) { System.out.print(""); if (thTest01.isComplete() && thTest02.isComplete()) { break; } } System.out.println("总数为:" + (thTest01.getSum() + thTest02.getSum())); threaPool.shutdown(); } };
发表评论
文章已被作者锁定,不允许评论。
-
java WeakHashMap学习(key是弱引用)
2018-06-21 09:31 1232在Java集合中有一种特殊的Map类型:WeakHashMap ... -
java HashMap TreeMap(key顺序) LinkedHashMap(插入顺序)学习
2018-06-07 10:27 953java为数据结构中的映射定义了一个接口java.util.M ... -
java RESTful 详解
2018-04-27 11:35 643(1)每一个URI代表一种资源,独一无二; (2)客户端 ... -
java 通过HttpsUrlConnection访问接口数据
2018-04-19 11:25 990server: ssl: key-stor ... -
java 使用多线程的场景总结
2018-04-10 14:35 1704在一个高并发的网站中,多线程是必不可少的。下面先说一下多线程在 ... -
java Enum枚举设置
2018-04-10 10:55 480/** * 数据状态:0:无效,1:有效 **/ ... -
java RestTemplate访问restful服务
2018-03-01 15:02 1621REST的基础知识 当谈论REST时,有一种常见的错误就是将其 ... -
java FYOpenApi实现短信发送
2018-01-02 17:10 11741.配置文件 sms.OpenUrl = http://s ... -
java JSONObject序列化包含Date类型数据的Java对象
2017-12-26 16:31 1617如果Date.class无法进行转换则使用Timestamp. ... -
java 用HttpsURLConnection进行传递中文时错误总结
2017-12-07 16:42 654传递中文时需要用Writer而不是OutputStream ... -
java 内存泄漏
2017-11-27 13:51 4951.内存溢出 out of memory ... -
ActiveMQ 三种发送消息方式(同步,异步,单向)
2017-11-17 10:25 2453MQ 发送普通消息有三种实现方式:可靠同步发送、可靠异步发送、 ... -
java Guava ListenableFuture实现线程回调功能
2017-11-14 10:17 1775java Future具有局限性。在实际应用中,当需要下 ... -
java Curator实现分布式锁
2017-09-05 14:39 1090Curator实现分布式锁主要依赖于zookeeper ... -
java Guava工具集学习(强大)
2017-09-05 10:28 432import java.util.Iterator ... -
java CyclicBarrier进行并发编程
2017-08-25 15:44 673CyclicBarrier允许一组线程相互等待达到一个公共的障 ... -
java 几种性能优化的总结
2017-08-23 14:08 3251、使用StringBuilder 一般 ... -
java 使用kyro进行高性能序列化对象和集合
2017-08-23 14:05 2152import java.io.ByteArrayInp ... -
java 对重复电话号码进行排除的优化(排序和前后对比)
2017-08-22 14:14 7911.先对10万数据排序; 2.对比前后两条数据 ; 3.筛 ... -
ActiveMQ 结合Spring进行数据同步
2017-07-19 15:27 584注意事项hibernate配置文件必须设置自动提交否则不能插入 ...
相关推荐
本文将基于"java 多线程并发实例"这个主题,深入探讨Java中的多线程并发概念及其应用。 首先,我们要了解Java中的线程。线程是程序执行的基本单元,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈,而共享堆...
在Java中,实现多线程有两种主要方式:通过实现`Runnable`接口或者继承`Thread`类。 首先,让我们从创建线程开始。当你有一个实现了`Runnable`接口的类时,你可以创建一个`Thread`对象并传入你的`Runnable`实例,如...
4. **线程优先级与调度**:Java的`Thread`类提供了设置线程优先级的方法,如`setPriority(int priority)`,但实际线程调度依赖于操作系统的策略,优先级并不保证绝对的执行顺序。 5. **守护线程(Daemon)**:守护...
Java线程是多任务编程的重要概念,它允许程序同时执行多个独立的任务,从而...在"线程池.rar"和"线程实例"这两个文件中,你可以找到关于这些概念的具体示例代码,通过学习和实践,可以深入理解Java线程的运用和管理。
总结起来,"Java多线程实例图形版"是一个结合理论与实践的教学资源,通过“哲学家就餐问题”这一经典案例,帮助开发者理解多线程的基本概念、并发问题以及解决策略。通过学习这个实例,不仅可以掌握Java多线程编程的...
在Java中,实现多线程有两种主要方式:通过继承`Thread`类和实现`Runnable`接口。 1. 继承Thread类: 当你需要创建一个新的线程时,可以创建一个新类来继承`Thread`类。重写`run()`方法,在其中编写线程要执行的...
在本实例源码中,包含17个章节和上百个实例,旨在深入讲解Java多线程的核心概念和实际应用。 一、线程基础知识 在Java中,线程是程序的执行流,每个线程都有自己的程序计数器、虚拟机栈、本地方法栈和一部分堆内存...
Java 多线程实例 Java 多线程是Java编程语言的一个重要特性,它使得程序能够在同一时间执行多个任务,从而提高系统效率和资源利用率。本文将深入探讨Java中的线程概念、创建线程的方式以及如何实现线程的并发执行。...
总的来说,这个"java多线程实例"是一个实用的学习资源,它展示了如何利用Java的多线程特性进行高效的网络下载,并通过合理的线程同步和文件操作来实现资源的合并。对于想要深入理解Java多线程和网络编程的开发者来说...
本书“Java多线程编程实例”深入浅出地讲解了如何在Java环境中实现多线程操作,尽管出版时间较早,但其内容的经典性和实用性使其在现代开发中仍具有极高的参考价值。 首先,我们要理解Java中的线程是如何创建的。...
Java多线程是Java编程中的重要概念,尤其在并发编程领域有着广泛的...通过对"java多线程实例"的学习,开发者可以深入理解线程的工作原理,提升解决并发问题的能力,这对于开发高并发的网络服务、数据库应用等至关重要。
### Java多线程编程实例解析 #### 1. 创建线程的方式 在Java中,创建线程有两种主要方式:通过继承`Thread`类或实现`Runnable`接口。 - **继承Thread类**:创建一个新类继承自`Thread`,并重写其`run()`方法。在`...
在这个"Eclipse项目java线程实例"中,我们可以深入理解并实践Java线程的创建、管理和同步机制。 首先,Java线程允许程序同时执行多个不同的任务,从而提高系统的效率和响应性。Java提供了两种创建线程的方式:通过...
Java线程实例通常包括生产者消费者模型、哲学家就餐问题、银行家算法等经典案例,这些实例有助于理解线程的同步、协作和资源管理。 总结来说,Java线程是Java编程中不可或缺的一部分,理解和掌握线程的创建、同步、...
《Java多线程编程实例》这本书深入浅出地探讨了Java中的多线程编程,通过丰富的实例帮助读者理解和掌握这一复杂主题。随书源码提供了实际操作的机会,以便读者能够亲手实践书中的示例,加深理解。 1. **线程创建...
在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类 当创建一个新的线程时,可以通过创建Thread类的新实例并重写其run()方法来实现。run()方法包含线程要执行的代码。一旦调用...
`Thread`类是Java中的核心类,它允许我们创建并控制独立的执行线程。在这个实例中,我们将深入探讨如何使用`Thread`类创建和管理多线程。 1. **线程的基本概念** - **线程**:线程是程序执行的最小单元,一个进程...
在Java中,多线程可以通过实现Runnable接口或继承Thread类来创建。下面我们将深入探讨Java多线程编程的相关知识点。 1. **线程的创建** - 实现Runnable接口:这是推荐的方式,因为Java类只能单继承,通过实现...