交互に3回行うように1、サブスレッドの実行は、メインスレッド5つのラン、10回行います
public class Bussiness {
private boolean subFlag = true;//主线程和子线程切换的控制开关
public static void main(String[] args) {
final Bussiness bussiness = new Bussiness();
// 子线程
new Thread(new Runnable() {
public void run() {
for (int i = 0; i < 3; i++) {
bussiness.subMethod();
}
}
}).start();
// 主线程
for (int i = 0; i < 3; i++) {
bussiness.mainMethod();
}
}
public synchronized void mainMethod() {
while (subFlag) {
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < 5; i++) {
System.out.println(Thread.currentThread().getName()
+ " : main thread running loop count -- " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
subFlag = true;
notify();
}
public synchronized void subMethod() {
while (!subFlag) {
try {
wait();//在其他线程调用此对象的 notify() 方法或 notifyAll() 方法前,导致当前线程等待。
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int i = 0; i < 10; i++) {
System.err.println(Thread.currentThread().getName()
+ " : sub thread running loop count -- " + i);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
subFlag = false;
notify();//唤醒在此对象监视器上等待的单个线程。
}
}
2、100枚のチケットがあり、二つのウィンドウがあると同時に、チケットをつかむ、投票をつかむために、マルチスレッド・シミュレーション・エフェクトを使用してください
package threadLearning.threadSafeProblem;
/**
*
* @classDesc: 功能描述:需求现在有100张火车票,有两个窗口同时抢火车票,请使用多线程模拟抢票效果。
* @author: zjb
* @createTime: 创建时间:2018-6-23 下午11:12:29
* @version: v1.0
* @copyright:
*/
public class ThreadTrain1 implements Runnable {
private static int count = 100;
private static Object oj = new Object();
public void run() {
while (count > 0) {
try {
//Thread.sleep(1000);
} catch (Exception e) {
}
sale();
}
}
public void sale() {
// 前提 多线程进行使用、多个线程只能拿到一把锁。
// 保证只能让一个线程 在执行 缺点效率降低
/*如何解决线程同步问题:
方法1:使用同步代码块,如下;
方法2:使用同步函数:在方法上修饰synchronized 称为同步函数,如:
public synchronized void sale()
思考:同步函数使用this锁。证明方式: 一个线程使用同步代码块(this明锁),另一个线程使用同步函数。
如果两个线程抢票不能实现同步,那么会出现数据错误。
*/
synchronized (oj) {
if (count > 0) {
System.out.println(Thread.currentThread().getName() + ",出售第"
+ (100 - count + 1) + "票");
count--;
}
}
}
}
package threadLearning.threadSafeProblem;
/**
*
* @classDesc: 功能描述:
* @author: zjb
* @createTime: 创建时间:2018-6-23 下午11:24:14
* @version: v1.0
* @copyright:
*/
public class ObtainTest1 {
public static void main(String[] args) {
ThreadTrain1 threadTrain = new ThreadTrain1();
Thread obtainThread1 = new Thread(threadTrain, "1号窗口");
Thread obtainThread2 = new Thread(threadTrain, "2号窗口");
obtainThread1.start();
obtainThread2.start();
}
}
3、4秒の実行間隔一度タイマーを使用して、及び2つの第二間隔を行い、そう実行
タイマー:ツール、後にバックグラウンドスレッドで実行するようにスケジュールそのネジ付きタスクと。タスクを実行する、または定期的に繰り返すように配置することができ
、コンストラクタ:
タイマー(文字列名)は
、その関連するスレッド指定された名前を持つ新しいタイマーを作成します。
タイマー(文字列名、ブールisDaemon)は、
その関連するスレッド指定された名前を持つ新しいタイマーを作成し、あなたは、デーモンとして実行するように指定することができます。
方法:
空のスケジュール(TimerTaskをタスク、長い遅延)
スケジュール指定したタスク指定した遅延時間の経過後
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
public class TimerTastCus extends TimerTask {
private static volatile int count = 1;//确保每个执行器获取到的count值都是最新的
@Override
public void run() {
//实现一个值在0和1之前交替取值,进而使得执行器4秒,2秒交替执行
count = (count + 1) % 2;
System.err.println("count---》 "+count);
System.out.println("当前执行线程为-创建对象前->"+Thread.currentThread().getName());
new Timer().schedule(new TimerTastCus(), 2000+2000*count);
}
public static void main(String args[]) {
Timer timer = new Timer();
timer.schedule(new TimerTastCus(), 2000 + 2000 * count);//毫秒
while (true) {
try {
System.out.println("当前执行线程为-->"+Thread.currentThread().getName()+" 当前时间的秒数:-->"+new Date().getSeconds());
Thread.sleep(1000);//
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}