Java的第一个坑,多线程入门
来源:互联网 发布:拜年视频制作软件 编辑:程序博客网 时间:2024/05/22 17:05
起因是一道笔试题:
http://edisonxu.org/2017/03/02/java-thread-communication.html#comments
(上面这篇文章中提到的关于volatile的答案似乎有问题)
几个坑的地方:
1. wait() 和notify() 一定是在synchronized()块中出现
wait() 发生时会当前线程释放锁
notify()发生时,会?
2. notify() 出现在wait() 之前则无效(和条件变量的区别)
3. Integer虽然可以调用wait(),notify(),但是由于赋新值时会改变对象,所以不能用在这里,要自己定义一个类似的东西
我的代码:
1,Ojbect,synchronized,wait,notify版
package mytest;public class ThreadTest { static class ThreadNum{ public int i; public ThreadNum(int value){ i=value; } } private Object w1=new Object (); private Object w2=new Object(); private Object o=new Object(); private ThreadNum cur=new ThreadNum(1);//must use self-define type public Runnable newThreadOne() { return new Runnable() { public void run() { try { for (int i = 0; i < 52; i=i+2) { synchronized (cur) {//must inside synchronized block if(cur.i==2)//从逻辑上来说,只有两个线程if应该没问题;但是有个叫Spurious wakeup 的东西要求这个地方一定要用while,然而懒得改了 { cur.wait(); } System.out.print(i+1); System.out.print(i+2); cur.i=2; cur.notify(); } } } catch (InterruptedException e) { System.out.println("Oops..."); } } }; } public Runnable newThreadTwo() { return new Runnable() { public void run() { try { for (int i = 0; i < 26; i++) { synchronized (cur) { if(cur.i==1) { cur.wait(); } System.out.print((char)('a'+i)); cur.i=1; cur.notify(); } } } catch (InterruptedException e) { System.out.println("Oops..."); } } }; } public static void main(String args[]) throws InterruptedException { /* Object o=new Object(); synchronized (o) { o.notify(); System.out.println("notified"); o.wait(); System.out.println("wait"); }*/ ThreadTest test = new ThreadTest(); Thread t1=new Thread(test.newThreadOne()); Thread t2=new Thread(test.newThreadTwo()); t1.start(); t2.start(); }}
2.condition,lock,unlock,await,signal版
java的signal函数似乎一定是要持有锁的线程调用,这点和C的pthread_cond_t
不同
package mytest;import java.util.concurrent.locks.Condition;import java.util.concurrent.locks.Lock;import java.util.concurrent.locks.ReentrantLock;public class ConditionTest { private Lock lock=new ReentrantLock(true); private Condition condition1=lock.newCondition(); private Condition condition2=lock.newCondition(); private int thread_to_run=1; public Runnable newThreadOne() { return new Runnable() { public void run() { try { for (int i = 0; i < 52; i=i+2) { synchronized (lock) { while(thread_to_run!=1){ condition1.wait(); } System.out.print(i+1); System.out.print(i+2); condition2.signal(); } } } catch (InterruptedException e) { System.out.println("Oops..."); } } }; } public Runnable newThreadTwo() { return new Runnable() { public void run() { try { for (int i = 0; i < 26; i++) { synchronized (lock) { while(thread_to_run!=2){ condition2.await(); } System.out.print((char)('a'+i)); condition1.signal(); } } } catch (InterruptedException e) { System.out.println("Oops..."); } } }; } public static void main(String args[]) throws InterruptedException { /* Lock lock=new ReentrantLock(true); Condition condition1=lock.newCondition(); condition1.signal(); System.out.println("signal"); lock.lock(); System.out.println("before wait"); condition1.await(); System.out.println("wait"); condition1.signal(); System.out.println("signal"); lock.unlock(); */ ThreadTest test = new ThreadTest(); Thread t1=new Thread(test.newThreadOne()); Thread t2=new Thread(test.newThreadTwo()); t1.start(); t2.start(); t1.join(); t2.join(); }}
3.信号量 semaphore,acquire,release
个人感觉信号量的版本最简单,因为这是一个关于顺序控制的问题,所以信号量会直接管理一个相关的计数器,不用像前面的程序那样需要自己控制另外一个变量
package mytest;import java.util.concurrent.Semaphore;public class SemaphoreTest { static class ThreadNum{ public int i; public ThreadNum(int value){ i=value; } } private Semaphore w1=new Semaphore(1); private Semaphore w2=new Semaphore(0); public Runnable newThreadOne() { return new Runnable() { public void run() { try { for (int i = 0; i < 52; i=i+2) { w1.acquire(); System.out.print(i+1); System.out.print(i+2); w2.release(); } } catch (InterruptedException e) { System.out.println("Oops..."); } } }; } public Runnable newThreadTwo() { return new Runnable() { public void run() { try { for (int i = 0; i < 26; i++) { w2.acquire(); System.out.print((char)('a'+i)); w1.release(); } } catch (InterruptedException e) { System.out.println("Oops..."); } } }; } public static void main(String args[]) throws InterruptedException { ThreadTest test = new ThreadTest(); Thread t1=new Thread(test.newThreadOne()); Thread t2=new Thread(test.newThreadTwo()); t1.start(); t2.start(); t1.join(); t2.join(); }}
参考:
1.异常
http://blog.csdn.net/historyasamirror/article/details/6709693
2.条件变量
http://blog.csdn.net/woshixuye/article/details/28283289
3.
阅读全文
0 0
- Java的第一个坑,多线程入门
- java第一个入门程序
- java入门的第一个程序代码 hello world
- java多线程入门例子-第一例
- Java入门之Java第一个程序
- java中入门代码第一个
- Java入门第一个程序:Hello World!
- 我的第一个多线程源码
- ExtJS的入门第一个程序
- Hibernate 入门的第一个程序
- opengl 入门的第一个基础实验
- Struts2入门的第一个应用
- WINCE入门的第一个驱动程序
- SpringMVC的第一个入门案例
- storm入门--storm的第一个示例
- SpringMVC的第一个入门案例
- 人生的第一个springboot入门项目
- JavaSE第一讲:JavaSE入门、JDK的下载与安装、第一个Java程序、Java程序的编译与执行
- jquery源码解析
- 数据可视化matplotlib(01) 图的选择
- nhmicro技术框架应用说明(事务、aop、分库分表、读写分离)
- IO流(一)
- BroadCast Receiver详解
- Java的第一个坑,多线程入门
- 一个子系统的配置
- MySQL 体系架构 Oracle体系架构 PostgreSQL体系架构
- C#(KeyChar)键值对照表
- 计算机等级考试--四级网络工程师1
- Android四大组件详解
- 干货 | 台大“一天搞懂深度学习”课程PPT(下载方式见文末!!)
- okhttp的https的使用
- Mysql同步数据案列