Java的第一个坑,多线程入门
2017-11-15 11:53
323 查看
起因是一道笔试题:
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.异常
http://blog.csdn.net/historyasamirror/article/details/6709693
2.条件变量
http://blog.csdn.net/woshixuye/article/details/28283289
3.
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.
相关文章推荐
- java入门学习:多线程创建-Thread,Runnable,callable和threadpool
- java 多线程入门
- 1、Java SE入门、jdk及第一个java程序
- [Thinking in Java] - No.7 Java多线程入门
- Java入门到精通——基础篇之多线程实现简单的PV操作的进程同步
- java多线程入门:wait、notify、notifyAll函数介绍
- 黑马程序员——Java多线程入门
- Java入门——(4)多线程
- java多线程入门知识及示例程序
- JAVA笔记:多线程入门
- JavaSE第一讲:JavaSE入门、JDK的下载与安装、第一个Java程序、Java程序的编译与执行
- java 基础之入门第一个坑 错误:找不到或无法加载主类
- 1 Java 多线程入门大全(适用于有一定基础者)
- Java SE入门、JDK的下载与安装、第一个Java程序、Java程序的编译与执行
- java入门学习(15)—多线程
- Gradle入门(3):构建第一个Java项目
- Java多线程系列——从菜鸟到入门
- Java 多线程入门大全
- java 多线程入门实例
- Java多线程程序设计入门