java多线程共享对象切换标示
java多线程共享对象切换标志
直接上题:
要求创建三个线程,输出1-90, 最开始第一个线程输出1-5,第二个输出6-15,第三个输出16-30
接着再第一个线程输出31-35, 再第二个36-45,再第三个46-60...就这样循环下去,直到打印出90个数。
与互联网其他解决输出 1~75有差异,并且有些是错误,线程不安全的,这里进行常规方法改进。
jdk版本提升7,8后,synchronized大幅得以提升。
解决办法:通俗处理方式,简单易理解,使用共享对象,使用标志位转移线程状态,比较灵活。
package com.dennis.study.thread; /** * 要求创建三个线程,输出1-90, 最开始第一个线程输出1-5,第二个输出6-15,第三个输出16-30 * 接着再第一个线程输出31-35, 再第二个36-45,再第三个46-60...就这样循环下去,直到打印出90个数 * 解决办法:通俗处理方式,简单易理解,使用共享对象,使用标志位转移线程状态,比较灵活。 * * @author dennis * */ public class Thread3_1to90 { static ShareData3_ sd = new ShareData3_(1); public static void main(String[] args) { new Thread(new Runnable() { @Override public void run() { sd.print1(); } }).start(); new Thread(new Runnable() { @Override public void run() { sd.print2(); } }).start(); new Thread(new Runnable() { @Override public void run() { sd.print3(); } }).start(); while (Thread.activeCount() > 0) { Thread.currentThread().setDaemon(true); } } } class ShareData3_ { private static int num = 0; private volatile int flag = 1; private final static int end = 90; public ShareData3_( int f) { this.flag = f; } /** * 1~5 31~35,61~65, */ public synchronized void print1() { while(num < end) { while(flag > 1) { wait_(); } while (num % 30 < 5 && num < end) { for (int i = 0; i < 5; i++) { System.out.println("print1 = " + Thread.currentThread().getName() + "\t" + ++num); } } sleep_(); flag = 2; notifyAll(); } } /** * 6~15 36~45,66~75, */ public synchronized void print2() { while(num <end) { while(flag != 2) { wait_(); } while (num % 30 < 15 && num % 30 > 4 && num < end) { for (int i = 0; i < 10; i++) { System.out.println("print2 = " + Thread.currentThread().getName() + "\t" + ++num); } } sleep_(); flag = 3; notifyAll(); } } /** * 16~30 46~60,76~90, */ public synchronized void print3() { while(num < end) { while(flag < 3) { wait_(); } while (num % 30 > 14 && num < end) { for (int i = 0; i < 15; i++) { System.out.println("print3 = " + Thread.currentThread().getName() + "\t" + ++num); } } sleep_(); flag = 1; notifyAll(); } } private final void sleep_() { try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } private final void wait_() { try { wait(); } catch (InterruptedException e) { e.printStackTrace(); } } }
记录使用 ^_^