Java synchronized用法 | join用法

一、对于synchronized:

使用环境:多线程的同步机制对资源加锁,使得只有一个线程可以操作,同步用于解决多线程同时访问某一个资源出现的问题。同步机制使用synchronized关键字实现。

用法:

1. 修饰一个方法,这个方法就叫做同步方法。但是,同步加锁的是对象,而不是代码。

class Book extends Thread 
{
	private int id; 
	public Book(int v)
	{ 
		id = v; 
	} 
	public synchronized void Print(int v) 
	{ 
		while(true) 
			System.out.println(v); 
	} 
	public void run()
	{ 
		Print(id); 
	} 
}
public class SyncTest {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Book b1 = new Book(0); 
		b1.start(); 
		Book b2 = new Book(1);
		b2.start(); 
	}
}

输出结果:两本书b1,b2各自运行输出,互不影响。说明b1,b2两个实例都拿到了对自己的使用权,即synchronized关键字此处是对类的实例对象加锁。


2. 对一个资源加锁,synchronized(object)的用法,同步加锁的针对当前对象的object。

class Book extends Thread { 
	private int count=0; 
	private int id; 
	public Book(int v) { 
		id = v; 
	} 
	public void printVal(int v) { 
		synchronized(Book.class) { 
			while(count++<=10)
				System.out.println(v); 
		} 
	} 
	public void run() { 
		printVal(id); 
	} 
} 

public class SyncTest {

	public static void main(String[] args) {
		Book b1 = new Book(0); 
		b1.start(); 
		Book b2 = new Book(1);
		b2.start(); 
	}
}

输出结果:先输出b1的0,再输出b2的1。说明此时是对类上锁,b1先拿到了类Book的使用权,之后b2才拿到,即synchronized此时对synchronized(object)的object上锁。

上面的例子有个缺点,用到同步就希望将性能的损失降到最低,因为同步的资源“越大”,损失的性能就越多,再看上面的例子是对整个类加锁,粒度太大,换一种思路,如果我们对类中的静态变量(static)加锁,由于静态变量是全局的,所有类的实例共用它,也可以达到上面的目的。

也就是说,在达到同样目的的时候,我们要尽量控制synchronized(object)中object的大小。

class Book extends Thread { 
	
	private int count=0; 
	private int id; 
	private static Object lock=new Object();
	public Book(int v) { 
		id = v; 
	} 
	public void printVal(int v) { 
		synchronized(lock) { 
			while(count++<=10)
				System.out.println(v); 
		} 
	} 
	public void run() { 
		printVal(id); 
	} 
} 

public class SyncTest {

	public static void main(String[] args) {
		Book f1 = new Book(0); 
		f1.start(); 
		Book f2 = new Book(1);
		f2.start(); 
	}
}


3. 对 一个方法中的一个区块加锁,synchronized(this){ /* block */ },表示只对这个区块的资源实行互斥访问,它的作用域是当前对象。

注意:

(1). 当一个线程访问object的一个synchronized(this)同步代码块时,另一个线程仍然可以访问该object中的非synchronized(this)同步代码块。

(2). 当一个线程访问object的一个synchronized(this)同步代码块时,其他线程对object中所有其它synchronized(this)同步代码块的访问将被阻塞。可以这么理解,当一个线程访问object的一个synchronized(this)同步代码块时,它就获得了这个object的对象锁。结果,其它线程对该object对象所有同步代码部分的访问都被暂时阻塞。


4. synchronized关键字是不能继承的,也就是说,基类的方法synchronized method(){} 在继承类中并不自动是synchronized method(){},而是变成了method(){}。继承类需要你显式的指定它的某个方法为synchronized方法。


二、对于join:

join用于主线程等待子线程运行完毕它的run方法,再继续执行下面的代码。例如:

public class ThreadTester {
	
	public static void main(String[] args) throws InterruptedException{
		Thread t1=new Thread(new ThreadTesterA());
		Thread t2=new Thread(new ThreadTesterB());
		t1.start();
		t1.join(); //t1线程完成run方法后才会继续执行下面的代码!
		t2.start();
		t2.join();		
	}	
}


class ThreadTesterA implements Runnable{

	private int i;
	
	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(i<10){
			System.out.print("i="+i+" ");
			i++;
		}
		System.out.println();
	}
}

class ThreadTesterB implements Runnable{
	
	private int j;

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(j<10){
			System.out.print("j="+j+" ");
			j++;
		}
		System.out.println();
	}
}







  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1. 目录 1. 2. 目录 .........................................................................................................................................................1 JVM ...................................................................面试.................................................................................... 19 2.1. 线程 ...................................................................................................................................................... 20 2.2. JVM 内存区域 ..................................................................................................................................... 21 2.2.1. 程序计数器(线程私有) ................................................................................................................ 22 2.2.2. 虚拟机栈(线程私有) .................................................................................................................... 22 2.2.3. 本地方法区(线程私有) ................................................................................................................ 23 2.2.4. 堆(Heap-线程共享)-运行时数据区 ...................................................................................... 23 2.2.5. 方法区/永久代(线程共享) ..................................................................................................... 23 2.3. JVM 运行时内存 ................................................................................................................................. 24 2.3.1. 新生代 .......................................................................................................................................... 24 2.3.1.1. 2.3.1.2. 2.3.1.3. 2.3.1.4. Eden 区 .................................................................................................................................................... 24 ServivorFrom........................................................................................................................................... 24 ServivorTo ...........................................

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值