java多线程学习(三)

总结:

本篇主要说明synchronized(this)代码块使用,这种方式和synchronized方法都是锁定的对象实例,都是同步的,阻塞的.不同的是,synchronized(this)代码块之外的代码可以异步调用

1,syn代码块减少阻塞时间

syn方法会阻塞其他线程,通过改成syn代码块,能减少等待时间

package chapter2.synBlock;

public class CommonUtils {
	public static long beginTime1;
	public static long endTime1;
	public static long beginTime2;
	public static long endTime2;
}
package chapter2.synBlock;

public class MyThread1 extends Thread {
	private Task task;
	public MyThread1(Task ta){
		super();
		this.task=ta;
	}
	@Override
	public void run(){
		super.run();
		CommonUtils.beginTime1=System.currentTimeMillis();
		task.longTimeTask();
		CommonUtils.endTime1=System.currentTimeMillis();
	}
}
package chapter2.synBlock;

public class MyThread2 extends Thread {
	private Task task;
	public MyThread2(Task ta){
		super();
		this.task=ta;
	}
	@Override
	public void run(){
		super.run();
		CommonUtils.beginTime2=System.currentTimeMillis();
		task.longTimeTask();
		CommonUtils.endTime2=System.currentTimeMillis();
	}
}
package chapter2.synBlock;
/*
 * 本例对比chapter2.synBlemish包的,将syn方法改为syn代码块,运行时间缩短到3s,
 * 因为b线程不用等待a线程的执行的sleep过程了,只需要等待a的赋值过程,
 * a,b线程同时进入longTimeTask方法,sleep过程是同时进行的,
 * 原先的syn方法,如果有n个线程,需要执行3*n的时间,而现在只需要3s,
 * 需要分清是执行的过程需要同步,还是赋值过程需要同步(防止脏读),
 * 只需要将需要同步的代码块加上syn,其他部分执行可以并发,节约时间
 * 以下是输出
begin task
begin task
长时间处理任务后从远程返回的值1 Thread name=Thread-1
长时间处理任务后从远程返回的值1 Thread name=Thread-0
长时间处理任务后从远程返回的值2 Thread name=Thread-0
end task
长时间处理任务后从远程返回的值2 Thread name=Thread-0
end task
耗时:3s


 */
public class Run {

	public static void main(String[] args) {
		Task task=new Task();
		MyThread1 mt1=new MyThread1(task);
		MyThread2 mt2=new MyThread2(task);
		mt1.start();
		mt2.start();
		//程序实际执行时间是这边的sleep的10s,因为如果注释掉这边的sleep,
//		会导致main线程不论mt1,mt2线程是否执行完成都执行后面的耗时计算,返回0s,
		try {
			Thread.sleep(10000);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		long beginTime=CommonUtils.beginTime1;
		if(CommonUtils.beginTime2<CommonUtils.beginTime1){
			beginTime=CommonUtils.beginTime2;
		}
		long endTime=CommonUtils.endTime1;
		if(CommonUtils.endTime2>CommonUtils.endTime1){
			endTime=CommonUtils.endTime2;
		}
		System.out.println("耗时:"+((endTime-beginTime)/1000)+"s");
	}

}
package chapter2.synBlock;

public class Task {
	private String getData1;
	private String getData2;
	public  void longTimeTask(){
		try{
			System.out.println("begin task");
			Thread.sleep(3000);
			String privateGetData1="长时间处理任务后从远程返回的值1 Thread name="+
					Thread.currentThread().getName();
			String privateGetData2="长时间处理任务后从远程返回的值2 Thread name="+
					Thread.currentThread().getName();
			synchronized (this) {
				getData1=privateGetData1;
				getData2=privateGetData2;
			}
			System.out.println(getData1);
			System.out.println(getData2);
			System.out.println("end task");
		}catch(InterruptedException e){
			e.printStackTrace();
		}
	}
}

一半同步一半异步

package chapter2.t7;
/*
 * 演示syn代码块同步的,不在syn块中的代码块是异步调用的,而在syn块中的是同步调用的
 * 输出截取:
 * nonSynchronized thread name=a i=0
nonSynchronized thread name=b i=0
nonSynchronized thread name=b i=1
nonSynchronized thread name=b i=2
nonSynchronized thread name=b i=3
nonSynchronized thread name=a i=1
上面说非syn块中的执行是不同步的
进入syn代码块是排队执行的
 */
public class Run {

	public static void main(String[] args) {
		Task task=new Task();
		ThreadA ta=new ThreadA(task);
		ThreadB tb=new ThreadB(task);
		ta.setName("a");
		tb.setName("b");
		ta.start();
		tb.start();
	}

}
package chapter2.t7;

public class Task {
	public void doLontTimeTask(){
		for(int i=0;i<100;i++){
			System.out.println("nonSynchronized thread name="+Thread.currentThread().getName()+
					" i="+i);
		}
		System.out.println("");
		synchronized (this) {
			for(int i=0;i<100;i++){
				System.out.println("Synchronized thread name="+Thread.currentThread().getName()+
						" i="+i);
			}
		}
	}
}
package chapter2.t7;

public class ThreadA extends Thread {
	Task task;
	public ThreadA(Task task) {
		super();
		this.task=task;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		task.doLontTimeTask();
	}
}
package chapter2.t7;

public class ThreadB extends Thread {
	Task task;
	public ThreadB(Task task) {
		super();
		this.task=task;
	}
	@Override
	public void run() {
		// TODO Auto-generated method stub
		super.run();
		task.doLontTimeTask();
	}
}

参考:<java多线程编程核心技术>

猜你喜欢

转载自blog.csdn.net/qq467215628/article/details/80202204