课本P150
https://www.cnblogs.com/xiaoxi/p/7679470.html
volatile不能保证原子操作,用synchronized关键字修饰方法能保持同步。按题目“如何将某个对象的A方法内的一个代码块和另一个方法B实现同步”,可以将对象的A方法内的一个代码块用synchronized修饰,另一个方法B也用synchronized修饰,就能实现同步。但是好乱,让代码块和方法同步?我不太懂。课本例9.8是生成两个线程
class threadA implements Runnable {
int i=0;
public void geti(int i_){
i=i_;
}
public void run(){
try {
do{
System.out.println("threadB is running!");
Thread.sleep(2000); //这里时间越短越准
}while(i==0);
}
catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("threadB is stopped.");
}
}
class threadB implements Runnable {
threadA A;
public void run(){
try {
Thread.sleep(10000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("threadA has run 10s.");
A.geti(1);
}
public void getA(threadA _A){
A=_A;
}
}
public class book0909_0 {
public static void main(String[] args){
threadA b=new threadA();
threadB a=new threadB();
a.getA(b);
Thread A=new Thread(a);
Thread B=new Thread(b);
A.start(); System.out.println("threadA starts.");
B.start(); System.out.println("threadB starts.");
}
}
开始的时候A和B写反了,不要介意。最后发现题做错了。
分析一下,B线程执行10s后,被A线程中止。
前面一句应该是不论A,B线程执行顺序,只要B执行了10s就会发生;后一句是被A中止,应该是传递了消息然后A使B被中止。
如果A可以知道B运行了多久就好了,目前想还是在B里面sleep,到点后接受A的消息。
class threadA1 implements Runnable {
threadB1 b;
public void getB(threadB1 _A){
b=_A;
}
public void run(){
System.out.println("threadA is running!");
System.out.println("threadA trys to stop threadB.");
b.geti(1);
}
}
class threadB1 implements Runnable {
int i=0;
public void geti(int i_){
i=i_;
}
public void run(){
System.out.println("threadB is running!");
do{
try {
Thread.sleep(10000);
System.out.println("threadB has run 10s.");
} catch (InterruptedException e) {
e.printStackTrace();
}
}while(i==0);
System.out.println("threadB is stopped.");
}
}
public class book0909_1 {
public static void main(String[] args){
threadA1 a=new threadA1();
threadB1 b=new threadB1();
a.getB(b);
Thread A=new Thread(a);
Thread B=new Thread(b);
B.start();
A.start();
}
}
同学提到可以用唤醒,但是A就必须拿到B的时间,目前得到其他线程运行时间和主动停止其他线程的方法还没有学到。
补充题
1.
volatile指示JVM这个变量是不稳定的,每次使用它都到主存中进行读取。一般来说,多线程环境下各线程间的共享变量都应该加volatile修饰。
class shaoshui implements Runnable {
public int t=0;
public void run(){
System.out.println("thread2烧水线开始:\t"+t);
try {
System.out.println("thread2开始洗水壶:\t"+t);
Thread.sleep(1000);
t=t+1;
System.out.println("thread2完成洗水壶:\t"+t);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
System.out.println("thread2开始烧水:\t"+t);
Thread.sleep(15000);
t=t+15;
System.out.println("thread2完成烧水:\t"+t);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
/* public shaoshui(int _t){
t=_t;
}*/
}
public class edit0902 {
public int gettime(shaoshui a){
return a.t;
}
public static void main(String[] args){
int t2=0;
shaoshui a=new shaoshui();
Thread SS=new Thread(a);
SS.start();
try {
System.out.println("thread1开始洗茶壶:\t"+t2);
Thread.sleep(1000);
t2=t2+1;
System.out.println("thread1完成洗茶壶:\t"+t2);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
System.out.println("thread1开始洗茶杯:\t"+t2);
Thread.sleep(2000);
t2=t2+2;
System.out.println("thread1完成洗茶杯:\t"+t2);
} catch (InterruptedException e) {
e.printStackTrace();
}
try {
System.out.println("thread1开始拿茶叶:\t"+t2);
Thread.sleep(1000);
t2=t2+1;
System.out.println("thread1完成拿茶叶:\t"+t2);
} catch (InterruptedException e) {
e.printStackTrace();
}
try{SS.join();}
catch(InterruptedException e) {}
System.out.println("可以泡茶");
}
}