知识点
01)线程间通信——示例代码

- public class InputOutputThread {
- public static void main(String[] args) {
- Res r = new Res();//资源
- Input in = new Input(r);
- Output out = new Output(r);
- Thread t1 = new Thread(in);
- Thread t2 = new Thread(out);
- t1.start();
- t2.start();
- }
- }
- class Res{
- String name;
- String an;
- }
- class Input implements Runnable{
- private Res r;
- Input(Res r){
- this.r = r;
- }
- public void run(){
- int x = 0;
- while(true){
- if (x == 0){
- r.name = "汤姆";
- r.an = "猫咪";
- }else{
- r.name = "杰瑞";
- r.an = "老鼠";
- }
- x = (x + 1) % 2;
- }
- }
- }
- class Output implements Runnable{
- private Res r;
- Output(Res r){
- this.r = r;
- }
- public void run(){
- while(true)
- System.out.println(r.name + "是: " + r.an);
- }
- }//陷入死循环中~
02)解决安全问题。
- public class InputOutputThread_2 {
- public static void main(String[] args) {
- Res_2 r = new Res_2();//资源
- Input_2 in = new Input_2(r);
- Output_2 out = new Output_2(r);
- Thread t1 = new Thread(in);
- Thread t2 = new Thread(out);
- t1.start();
- t2.start();
- }
- }
- class Res_2{
- String name;
- String an;
- }
- class Input_2 implements Runnable{
- private Res_2 r;
- Input_2(Res_2 r){
- this.r = r;
- }
- public void run(){
- int x = 0;
- while(true){
- synchronized(r){//同一个锁。
- if (x == 0){
- r.name = "汤姆";
- r.an = ".猫.咪.";
- }else{
- r.name = "杰瑞";
- r.an = "老...鼠";
- }
- x = (x + 1) % 2;
- }
- }
- }
- }
- class Output_2 implements Runnable{
- private Res_2 r;
- Output_2(Res_2 r){
- this.r = r;
- }
- public void run(){
- while(true)
- synchronized(r){//同一个锁。
- System.out.println(r.name + "是: " + r.an);
- }
- }
- }
03)等待唤醒机制
- /*
- * 等待唤醒机制。
- *
- * wait();
- * notify();
- * notifyAll();
- * 都使用在同步中,因为要对持有监视器(锁)的线程进行操作。
- * 所以要使用在同步中,因为只有同步才具有锁。
- *
- * 为什么这些操作线程的方法要定义在Object类中呢?
- * 因为这些方法在操作同步中线程时,都必须要标识它们所操作线程所持有的锁。
- * 只有同一个锁上的被等待线程,可以被同一个锁上notify唤醒,不可以对不同锁上的notify唤醒。
- * 也就是等待和唤醒必须是在同一个锁内。
- * 而锁可以是任意对象,所以可以被任意对象调用的方法就定义在Object类中。
- */
- public class InputOutputThread_3 {
- public static void main(String[] args) {
- Res_3 r = new Res_3();//资源
- Input_3 in = new Input_3(r);
- Output_3 out = new Output_3(r);
- Thread t1 = new Thread(in);
- Thread t2 = new Thread(out);
- t1.start();
- t2.start();
- }
- }
- class Res_3{
- String name;
- String an;
- boolean flag = false;
- }
- class Input_3 implements Runnable{
- private Res_3 r;
- Input_3(Res_3 r){
- this.r = r;
- }
- public void run(){
- int x = 0;
- while(true){
- synchronized(r){//同一个锁。
- if (r.flag)//如果为真,等待。
- try{r.wait();}catch(Exception e){}
- if (x == 0){
- r.name = "汤姆";
- r.an = ".猫.咪.";
- }else{
- r.name = "杰瑞";
- r.an = "老...鼠";
- }
- x = (x + 1) % 2;
- r.flag = true;//将flag设置为真。
- r.notify();//唤醒另外一个线程。
- }
- }
- }
- }
- class Output_3 implements Runnable{
- private Res_3 r;
- Output_3(Res_3 r){
- this.r = r;
- }
- public void run(){
- while(true){
- synchronized(r){//同一个锁。
- if (!r.flag)//如果为假,等待。
- try{r.wait();}catch(Exception e){}
- System.out.println(r.name + "是: " + r.an);
- r.flag = false;//将falg设置为false。
- r.notify();//唤醒另外一个线程。
- }
- }
- }
- }
04)代码优化
- /*
- * 代码的优化。
- */
- public class InputOutputYouHua {
- public static void main(String[] args) {
- ResY r = new ResY();//资源
- new Thread(new InputY(r)).start();
- new Thread(new OutputY(r)).start();
- }
- }
- class ResY{
- String name;
- String an;
- boolean flag = false;
- public synchronized void set(String name, String an){
- if (flag)
- try{this.wait();}catch(Exception e){}
- this.name = name;
- this.an = an;
- this.flag = true;//将flag设置为真。
- this.notify();//唤醒另外一个线程。
- }
- public synchronized void out(){
- if (!flag)
- try{this.wait();}catch(Exception e){}
- System.out.println(name + "是: " + an);
- this.flag = false;//将flag设置为真。
- this.notify();//唤醒另外一个线程。
- }
- }
- class InputY implements Runnable{
- private ResY r;
- InputY(ResY r){
- this.r = r;
- }
- public void run(){
- int x = 0;
- while(true){
- if (x == 0)
- r.set("汤姆", ".猫.咪.");
- else
- r.set("杰瑞", "老...鼠");
- x = (x + 1) % 2;
- }
- }
- }
- class OutputY implements Runnable{
- private ResY r;
- OutputY(ResY r){
- this.r = r;
- }
- public void run(){
- while(true)
- r.out();
- }
- }
05)线程中通信——生产者消费
- /*
- * 对于多个生产者和消费者。
- * 为什么要定义while判断标记。
- * 原因:需要让被唤醒的线程再一次判断标记。
- *
- * 为什么定义notifyAll();
- * 因为需要唤醒对方的线程。
- * 因为只有notify()的话,容易只唤醒本方线程的情况。导致程序中的所有线程都等待。
- */
- public class PrdCemDemo {
- public static void main(String[] args) {
- Resource r = new Resource();//共享资源
- new Thread(new Producer(r)).start();//生产线程0
- new Thread(new Producer(r)).start();//生产线程1
- new Thread(new Consumer(r)).start();//消费线程2
- new Thread(new Consumer(r)).start();//消费线程3
- }
- }
- class Resource{
- private String name;
- private int count = 1;
- private boolean flag = false;
- public synchronized void set(String name){//生产商品
- while (flag)
- try{
- this.wait();
- }catch(Exception e){
- }
- this.name = name + "----" + count++;
- System.out.println(Thread.currentThread().getName() + "...生产者" + this.name);
- flag = true;
- this.notifyAll();
- }
- public synchronized void out(){//出售商品
- while (!flag)
- try{
- this.wait();
- }catch(Exception e){
- }
- System.out.println(Thread.currentThread().getName() + "...消费者..." + this.name);
- flag = false;
- this.notifyAll();
- }
- }
- class Producer implements Runnable{
- private Resource r;
- Producer(Resource r){
- this.r = r;
- }
- public void run(){
- while(true){
- r.set("+商品+");
- }
- }
- }
- class Consumer implements Runnable{
- private Resource r;
- Consumer(Resource r){
- this.r = r;
- }
- public void run(){
- while(true){
- r.out();
- }
- }
- }
运行结果如下图所示:

06)生产消费者升级版(JDK1.5版本开始之后)
- /*
- * 从JDK1.5版本开始,提供了多线程的解决方案。
- * 将同步synchronzied替换成现有的Lock方案。
- * 将Object中的wait、notify、notifyAll,替换成了Condition对象。
- * 该对象可以Lock锁,进行获取。
- */
- public class PrdCemSuperDemo {
- public static void main(String[] args) {
- ResourceSup r = new ResourceSup();//共享资源
- new Thread(new ProducerSup(r)).start();//生产线程0
- new Thread(new ProducerSup(r)).start();//生产线程1
- new Thread(new ConsumerSup(r)).start();//消费线程2
- new Thread(new ConsumerSup(r)).start();//消费线程3
- }
- }
- class ResourceSup{
- private String name;
- private int count = 1;
- private boolean flag = false;
- private Lock lock = new ReentrantLock();
- private Condition con_c = lock.newCondition();//生产者标记
- private Condition con_p = lock.newCondition();//消费者标记
- public void set(String name) throws InterruptedException{//生产商品
- lock.lock();//获取锁。
- try{
- while (flag)
- con_c.await();//生产者线程等待。
- this.name = name + "----" + count++;
- System.out.println(Thread.currentThread().getName() + "...生产者" + this.name);
- flag = true;
- con_p.signal();//唤醒消费者线程。
- }finally{
- lock.unlock();//释放锁
- }
- }
- public void out() throws InterruptedException{//出售商品
- lock.lock();//获取锁
- try{
- while (!flag)
- con_p.await();//消费者线程等待。
- System.out.println(Thread.currentThread().getName() + "...消费者..." + this.name);
- flag = false;
- con_c.signal();//唤醒生产者线程。
- }finally{
- lock.unlock();//释放锁。
- }
- }
- }
- class ProducerSup implements Runnable{
- private ResourceSup r;
- ProducerSup(ResourceSup r){
- this.r = r;
- }
- public void run(){
- while(true){
- try{
- r.set("+商品+");
- }catch(InterruptedException e){
- }
- }
- }
- }
- class ConsumerSup implements Runnable{
- private ResourceSup r;
- ConsumerSup(ResourceSup r){
- this.r = r;
- }
- public void run(){
- while(true){
- try{
- r.out();
- }catch(InterruptedException e){
- }
- }
- }
- }
07)停止线程
- /*
- * stop方法以及过时。
- * 如果停止线程?
- * 只有一种方法,run方法结束。
- * 开启多线程运行,运行代码通常都是循环结构的,只要控制住循环,就可以让run方法结束,也就是线程结束。
- *
- * 特殊情况:当线程处于冻结状态,就不会读取到标记,那么线程就不会结束。
- *
- * 当没有指定的方式让冻结的线程恢复到运行状态时,这时需要对冻结状态进行清除。
- * 强制让线程恢复到运行状态,这样就可以操作标记让线程结束。
- * Thread提供了该方法:interrupt()
- */
- public class StopThreadDemo {
- public static void main(String[] args) {
- StopThread st = new StopThread();
- Thread t1 = new Thread(st);
- Thread t2 = new Thread(st);
- int num = 0;
- while(true){
- if(num++ == 60){
- // st.ChangeFlag();
- t1.interrupt();//强制清除状态。
- t2.interrupt();
- break;
- }
- System.out.println(Thread.currentThread().getName() + "...." + num);
- }
- }
- }
- class StopThread implements Runnable{
- private boolean flag = true;
- public synchronized void run(){
- while(flag){
- try{
- wait();
- }catch(InterruptedException e){
- System.out.println(Thread.currentThread().getName() + " ... InterruptedException");
- flag = false;
- }
- System.out.println(Thread.currentThread().getName() + " ... run");
- }
- }
- // public void ChangeFlag(){
- // flag = false;
- // }
- }
08)守护线程
- /*
- * 设置守护线程:setDaemon(true);也就是后台线程。
- * 注意:必须在开启线程之前设置。
- */
- public class SetDaemonThreadDemo {
- public static void main(String[] args) {
- SetDaemonThread st = new SetDaemonThread();
- Thread t1 = new Thread(st);
- Thread t2 = new Thread(st);
- t1.setDaemon(true);//设置为守护线程,也就是后台线程。
- t2.setDaemon(true);//注意:必须在开启线程之前设置。
- t1.start();
- t2.start();
- int num = 0;
- while(true){
- if(num++ == 60){
- // t1.interrupt();//强制清除状态。
- // t2.interrupt();
- break;
- }
- System.out.println(Thread.currentThread().getName() + "...." + num);
- }
- }
- }
- class SetDaemonThread implements Runnable{
- private boolean flag = true;
- public void run(){
- while(flag){
- System.out.println(Thread.currentThread().getName() + " ... run");
- }
- }
- }
09)join方法
- /*
- * Join:
- * 当t2线程执行到了t1线程的.join方法时,t2就会等待,等t1线程执行完,t2才会执行。
- * join用来临时加入线程执行。
- */
- public class JoinThreadDemo {
- public static void main(String[] args) throws InterruptedException{
- JoinThread jt = new JoinThread();
- Thread t1 = new Thread(jt);
- Thread t2 = new Thread(jt);
- t1.start();
- t1.join();//t1申请cup执行权。主线程main放弃执行权,变更为冻结状态。
- t2.start();
- for(int i = 0; i < 80; i++){
- System.out.println("Main..." + i);
- }
- }
- }
- class JoinThread implements Runnable{
- public void run(){
- for(int i = 0; i < 70; i++){
- System.out.println(Thread.currentThread().getName() + "..." + i);
- }
- }
- }
10) 优先级
- public class ToStringThreadDemo {
- public static void main(String[] args) throws InterruptedException{
- ToStringThread jt = new ToStringThread();
- Thread t1 = new Thread(jt);
- Thread t2 = new Thread(jt);
- t1.start();
- // t1.setPriority(Thread.MAX_PRIORITY);//设置优先级
- t2.start();
- for(int i = 0; i < 80; i++){
- System.out.println(Thread.currentThread().toString() + "Main..." + i);
- }
- }
- }
- class ToStringThread implements Runnable{
- public void run(){
- for(int i = 0; i < 70; i++){
- System.out.println(Thread.currentThread().toString() + "..." + i);
- Thread.yield();//暂停当前正在执行的线程对象,并执行其他线程。
- }
- }
- }
本文详细介绍了线程间的通信机制,包括同步、等待唤醒、生产者消费者模型等内容,并讲解了如何通过优化代码来提高线程间通信的效率。此外,还介绍了线程的管理技巧,如停止线程、守护线程、线程优先级等。
2293

被折叠的 条评论
为什么被折叠?



