* @author Administrator
*04_传智播客_张孝祥_传统线程同步通信技术
*synchronized这个表示我在执行的时候你就不能执行,互启
*/
public class TraditionalThreadCommunication {
public static void main(String[] args) {
Business business = new Business();
new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 5; i++) {
business.sub(i);
}
}
}).start();
for (int i = 0; i < 5; i++) {
business.main(i);
}
}
static class Business {
private boolean isSub = true; // 是子线程执行,false主线程执行
public synchronized void sub(int i) {
while (!isSub) {
// 不如果不是该子类执行
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 0; j < 1; j++) {
System.out.println("sub thread sequence of " + j + ",loop of " + i);
}
isSub = false;
this.notify();
}
public synchronized void main(int i) {
while (isSub) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
for (int j = 0; j < 2; j++) {
System.out.println("main thread sequence of " + j + ",loop of " + i);
}
isSub = true;
this.notify();
}
}
}
----------------------------------------------------------------------------------------------------------------------------------------------------------
下面是我刚看完面试题就暂停视频自己试着写的代码,还可以,结果完成要求了
在单次循环结束后让这个刚结束循环的线程休眠,保证另一个线程可以抢到执行权。
public class ThreadInterViewTest
{
/**
* 刚看到面试题没看答案之前试写
* 子线程循环10次,回主线程循环100次,
* 再到子线程循环10次,再回主线程循环100次
* 如此循环50次
*/
publicstatic void main(String[] args)
{
intnum = 0;
while(num++<50)
{
newThread(new Runnable()
{
@Override
publicvoid run()
{
circle("子线程运行", 10);
}
}).start();
try
{
//加这句是保证上边的子线程先运行,刚开始没加,主线程就先开了
Thread.sleep(2000);
}catch (InterruptedException e)
{
e.printStackTrace();
}
circle("主线程", 100);
}
}
publicstatic synchronized void circle(String name, int count)
{
for(int i=1; i<=count; i++)
{
System.out.println(name+"::"+i);
}
try
{
Thread.sleep(5000);
}catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
张老师讲的方法:
1、将子线程和主线程中要同步的方法进行封装,加上同步关键字实现同步
2、两个线程间隔运行,添加一个标记变量进行比较以实现相互通信,加色的部分
wait notify notifyAll wait会抛出异常
class Business
{
private boolean bShouleSub = true;
publicsynchronized void sub()
{
if (bShouleSub)
{
for (int i=1; i<11; i++)
SOP(sub+i);
bShouldSub= false;
this.notify();
}
else
this.wait();
}
publicsynchronized void main()
{
if (!bShouldSub)
{
for (int i=1; i<101; i++)
SOP(main+i);
bShouldSub= true;
this.notify();
}
else
this.wait();
}
}
经验:要用到共同数据(包括同步锁)或相同算法的多个方法要封装在一个类中
锁是上在代表要操作的资源类的内部方法中的,而不是上在线程代码中的。这样写出来的类就是天然同步的,只要使用的是同一个new出来的对象,那么这个对象就具有同步互斥特性
判断唤醒等待标记时使用while增加程序健壮性,防止伪唤醒