java-多线程

线程
在这里插入图片描述

在这里插入图片描述
代码
Thread
在这里插入图片描述

natice、异常

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

Runnable

在这里插入图片描述
代码
在这里插入图片描述

在这里插入图片描述

Thread和Runnable比较

Thread直接创建对象来创建线程
在这里插入图片描述

Runnable
在这里插入图片描述
总结
在这里插入图片描述

Thread也可以,因为Thread实现了Runnable接口,但是把他当成Runnable使用不如直接实现Runnable

线程的命名与取得

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

线程的休眠
在这里插入图片描述
如果被其他线程中断

第三种实现callable ***** 有返回值

在这里插入图片描述

在这里插入图片描述

优先级

main的优先级是5
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

线程的同步

在这里插入图片描述
加锁
在这里插入图片描述

这里的sleep是为了使看起来的效果更明显
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
在这里插入图片描述
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

自己测试的代码

package 多线程;

public class DC1 {
public static void main(String [] args) {
	xxl mt1 =new xxl("A");
	xxl mt2 =new xxl("B");
	xxl mt3 =new xxl("C");
	xx2 mt4 =new xx2("i");
	Thread t1=new Thread(mt1);
	Thread t2=new Thread(mt1);
	Thread t3=new Thread(mt1);
	t1.setPriority(10);
	t2.setPriority(5);
	System.out.println("t3的优先级:"+t3.getPriority());
	new xx2().run();
   t1.start();
   t2.start();
   t3.start();
	
	//new Thread(mt4).start();
}
}


  class xxl implements Runnable {
	  public xxl(String name) {
			super();
			this.name = name;
	  }
	  
	  public xxl(String name,int i) {
		super();
		this.name = name;
		this.i=i;
	}
	String name;
	int i=10;
	public void run(){
		synchronized(this) {
		for( ;i>2;i--)
			
			System.out.println(name+i);
		
	}
		}
	
}
  class xx2 implements Runnable {
	  
	  
	  public xx2() {
		super();
	}
	public xx2(String name2) {
		super();
		this.name2 = name2;
	}
	String name2;
	public void run(){
		/*
		 * for(int i=0;i<10;i++) System.out.println(Thread.currentThread().getName()+i);
		 */
		System.out.println("主线程名:"+Thread.currentThread().getName()+"  优先级:"+Thread.currentThread().getPriority());
	}
	
}

synchronized

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

1.方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程(就是在synchronized方法内部的线程)执行完该方法后,别的线程才能进入.

例如:

public synchronized void synMethod() {
//方法体
}

2.对某一代码块使用,synchronized后跟括号,括号里是变量,这样,一次只有一个线程进入该代码块.此时,线程获得的是成员锁.例如:

public int synMethod(int a1){
synchronized(a1) {
//一次只能有一个线程进入
}
}

3.synchronized后面括号里是一对象,此时,线程获得的是对象锁.例如:

public class MyThread implements Runnable {
public static void main(String args[]) {
MyThread mt = new MyThread();
Thread t1 = new Thread(mt, “t1”);
Thread t2 = new Thread(mt, “t2”);
Thread t3 = new Thread(mt, “t3”);
Thread t4 = new Thread(mt, “t4”);
Thread t5 = new Thread(mt, “t5”);
Thread t6 = new Thread(mt, “t6”);
t1.start();
t2.start();
t3.start();
t4.start();
t5.start();
t6.start();
}
public void run() {
synchronized (this) {
System.out.println(Thread.currentThread().getName());
}
}
}
对于3,如果线程进入,则得到当前对象锁,那么别的线程在该类所有对象上的任何操作都不能进行.在对象级使用锁通常是一种比较粗糙的方法。为什么要将整个对象都上锁,而不允许其他线程短暂地使用对象中其他同步方法来访问共享资源?如果一个对象拥有多个资源,就不需要只为了让一个线程使用其中一部分资源,就将所有线程都锁在外面。由于每个对象都有锁,可以如下所示使用虚拟对象来上锁:

class FineGrainLock {
MyMemberClass x, y;
Object xlock = new Object(), ylock = new Object();
public void foo() {
synchronized(xlock) {
//access x here
}
//do something here - but don’t use shared resources
synchronized(ylock) {
//access y here
}
}
public void bar() {
synchronized(this) {
//access both x and y here
}
//do something here - but don’t use shared resources
}
}

4.synchronized后面括号里是类,此时,线程获得的是对象锁.例如:

class ArrayWithLockOrder{
private static long num_locks = 0;
private long lock_order;
private int[] arr;
public ArrayWithLockOrder(int[] a)
{
arr = a;
synchronized(ArrayWithLockOrder.class) {//-----这里
num_locks++; // 锁数加 1。
lock_order = num_locks; // 为此对象实例设置唯一的 lock_order。
}
}
public long lockOrder()
{
return lock_order;
}
public int[] array()
{
return arr;
}
}
class SomeClass implements Runnable
{
public int sumArrays(ArrayWithLockOrder a1,
ArrayWithLockOrder a2)
{
int value = 0;
ArrayWithLockOrder first = a1; // 保留数组引用的一个
ArrayWithLockOrder last = a2; // 本地副本。
int size = a1.array().length;
if (size == a2.array().length)
{
if (a1.lockOrder() > a2.lockOrder()) // 确定并设置对象的锁定
{ // 顺序。
first = a2;
last = a1;
}
synchronized(first) { // 按正确的顺序锁定对象。
synchronized(last) {
int[] arr1 = a1.array();
int[] arr2 = a2.array();
for (int i=0; i<size; i++)
value += arr1[i] + arr2[i];
}
}
}
return value;
}
public void run() {
//
}
}

对于4,如果线程进入,则线程在该类中所有操作不能进行,包括静态变量和静态方法,实际上,对于含有静态方法和静态变量的代码块的同步,我们通常用4来加锁.

PS:synchronized 用法总结

synchronized用到不同地方对代码产生的影响:

  1. synchronized关键字修饰方法

假设P1、P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1、P2就都能够调用他们。

1
2
3
public synchronized void method(){
//
}
这也就是同步方法,那这时synchronized锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,他们之间会形成互斥,达到同步的效果。同时如果该对象中有多个同步方法,则当一个线程获执行对象中的一个synchronized方法,则该对象中其它同步方法也不允许别的线程执行。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了synchronized关键字的方法。

上边的示例代码等同于如下代码:

1
2
3
4
5
6
public void method() {
synchronized (this)
{
//…
}
}
此次就是一个P1对象的对象锁,哪个拿到了P1对象锁的线程,才能够调用P1的同步方法,而对P2而言,P1这个锁和他毫不相干,程式也可能在这种情形下摆脱同步机制的控制,造成数据混乱。

2.同步块,示例代码如下:

public void method() {
synchronized (this)
{
//…
}
}
这时,锁就是so这个对象,每个对象对应一个唯一的锁,所以哪个线程拿到这个对象锁谁就能够运行他所控制的那段代码。当有一个明确的对象作为锁时,就能够这样写程式,但当没有明确的对象作为锁,只是想让一段代码同步时,能够创建一个特别的instance变量(他得是个对象)来充当锁:

1
2
3
4
5
6
7
private byte[] lock = new byte[0];
Public void method(){
synchronized(lock)
{
//
}
}
注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。
3.将synchronized作用于static 函数,示例代码如下:

Class Foo
{
public synchronized static void method1()

{
//.
}
public void method2()
{
synchronized(Foo.class)
//
}
}

这两个同步方法都调用这个方法的对象所属的类的类锁(Class,而不再是由这个Class产生的某个具体对象了)。
能够推断:假如一个类中定义了一个synchronized的static函数A,也定义了一个synchronized 的instance函数B,那么这个类的同一对象Obj在多线程中分别访问A和B两个方法时,不会构成同步,因为他们的锁都不相同。A方法的锁是Obj所属的那个Class,而B的锁是Obj所属的这个对象。

Java 中 synchronized的用法详解(四种用法)

 更新时间:2015年11月09日 11:47:56   投稿:mrr  
Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。本文给大家介绍java中 synchronized的用法,对本文感兴趣的朋友一起看看吧

Java语言的关键字,当它用来修饰一个方法或者一个代码块的时候,能够保证在同一时刻最多只有一个线程执行该段代码。

 1.方法声明时使用,放在范围操作符(public等)之后,返回类型声明(void等)之前.这时,线程获得的是成员锁,即一次只能有一个线程进入该方法,其他线程要想在此时调用该方法,只能排队等候,当前线程(就是在synchronized方法内部的线程)执行完该方法后,别的线程才能进入.

例如:

?
1
2
3
public synchronized void synMethod() {
  //方法体
}

    2.对某一代码块使用,synchronized后跟括号,括号里是变量,这样,一次只有一个线程进入该代码块.此时,线程获得的是成员锁.例如:

?
1
2
3
4
5
public int synMethod( int a1){
  synchronized (a1) {
   //一次只能有一个线程进入
  }
}

    3.synchronized后面括号里是一对象,此时,线程获得的是对象锁.例如:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class MyThread implements Runnable {
   public static void main(String args[]) {
   MyThread mt = new MyThread();
   Thread t1 = new Thread(mt, "t1" );
   Thread t2 = new Thread(mt, "t2" );
   Thread t3 = new Thread(mt, "t3" );
   Thread t4 = new Thread(mt, "t4" );
   Thread t5 = new Thread(mt, "t5" );
   Thread t6 = new Thread(mt, "t6" );
   t1.start();
   t2.start();
   t3.start();
   t4.start();
   t5.start();
   t6.start();
  }
  public void run() {
   synchronized ( this ) {
    System.out.println(Thread.currentThread().getName());
   }
  }
}

    对于3,如果线程进入,则得到当前对象锁,那么别的线程在该类所有对象上的任何操作都不能进行.在对象级使用锁通常是一种比较粗糙的方法。为什么要将整个对象都上锁,而不允许其他线程短暂地使用对象中其他同步方法来访问共享资源?如果一个对象拥有多个资源,就不需要只为了让一个线程使用其中一部分资源,就将所有线程都锁在外面。由于每个对象都有锁,可以如下所示使用虚拟对象来上锁:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class FineGrainLock {
   MyMemberClass x, y;
   Object xlock = new Object(), ylock = new Object();
   public void foo() {
    synchronized (xlock) {
      //access x here
    }
    //do something here - but don't use shared resources
    synchronized (ylock) {
      //access y here
    }
   }
   public void bar() {
    synchronized ( this ) {
      //access both x and y here
    }
    //do something here - but don't use shared resources
   }
  }

 4.synchronized后面括号里是类,此时,线程获得的是对象锁.例如:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
class ArrayWithLockOrder{
  private static long num_locks = 0 ;
  private long lock_order;
  private int [] arr;
  public ArrayWithLockOrder( int [] a)
  {
   arr = a;
   synchronized (ArrayWithLockOrder. class ) { //-----这里
    num_locks++;       // 锁数加 1。
    lock_order = num_locks; // 为此对象实例设置唯一的 lock_order。
   }
  }
  public long lockOrder()
  {
   return lock_order;
  }
  public int [] array()
  {
   return arr;
  }
  }
  class SomeClass implements Runnable
  {
  public int sumArrays(ArrayWithLockOrder a1,
             ArrayWithLockOrder a2)
  {
   int value = 0 ;
   ArrayWithLockOrder first = a1;    // 保留数组引用的一个
   ArrayWithLockOrder last = a2;    // 本地副本。
   int size = a1.array().length;
   if (size == a2.array().length)
   {
    if (a1.lockOrder() > a2.lockOrder()) // 确定并设置对象的锁定
    {                   // 顺序。
     first = a2;
     last = a1;
    }
    synchronized (first) {       // 按正确的顺序锁定对象。
     synchronized (last) {
      int [] arr1 = a1.array();
      int [] arr2 = a2.array();
      for ( int i= 0 ; i<size; i++)
       value += arr1[i] + arr2[i];
     }
    }
   }
   return value;
  }
  public void run() {
   //
  }
  }

对于4,如果线程进入,则线程在该类中所有操作不能进行,包括静态变量和静态方法,实际上,对于含有静态方法和静态变量的代码块的同步,我们通常用4来加锁.

PS:synchronized 用法总结

synchronized用到不同地方对代码产生的影响:

1. synchronized关键字修饰方法

假设P1、P2是同一个类的不同对象,这个类中定义了以下几种情况的同步块或同步方法,P1、P2就都能够调用他们。

?
1
2
3
public synchronized void method(){
   //
}

这也就是同步方法,那这时synchronized锁定的是调用这个同步方法对象。也就是说,当一个对象P1在不同的线程中执行这个同步方法时,他们之间会形成互斥,达到同步的效果。同时如果该对象中有多个同步方法,则当一个线程获执行对象中的一个synchronized方法,则该对象中其它同步方法也不允许别的线程执行。但是这个对象所属的Class所产生的另一对象P2却能够任意调用这个被加了synchronized关键字的方法。

上边的示例代码等同于如下代码:

?
1
2
3
4
5
6
public void method()  { 
   synchronized ( this )  
  
     //.. 
  
}

此次就是一个P1对象的对象锁,哪个拿到了P1对象锁的线程,才能够调用P1的同步方法,而对P2而言,P1这个锁和他毫不相干,程式也可能在这种情形下摆脱同步机制的控制,造成数据混乱。

2.同步块,示例代码如下:

?
1
2
3
4
5
6
public void method() {
synchronized ( this )
{
//..
}
}

这时,锁就是so这个对象,每个对象对应一个唯一的锁,所以哪个线程拿到这个对象锁谁就能够运行他所控制的那段代码。当有一个明确的对象作为锁时,就能够这样写程式,但当没有明确的对象作为锁,只是想让一段代码同步时,能够创建一个特别的instance变量(他得是个对象)来充当锁:

?
1
2
3
4
5
6
7
private byte [] lock = new byte [ 0 ];
  Public void method(){ 
      synchronized (lock)
      {
        //
      }
  }

注:零长度的byte数组对象创建起来将比任何对象都经济――查看编译后的字节码:生成零长度的byte[]对象只需3条操作码,而Object lock = new Object()则需要7行操作码。

3.将synchronized作用于static 函数,示例代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
Class Foo 
   public synchronized static void method1() 
 
  
     //. 
  
   public void method2() 
  
     synchronized (Foo. class
     //
  
}

这两个同步方法都调用这个方法的对象所属的类的类锁(Class,而不再是由这个Class产生的某个具体对象了)。
能够推断:假如一个类中定义了一个synchronized的static函数A,也定义了一个synchronized 的instance函数B,那么这个类的同一对象Obj在多线程中分别访问A和B两个方法时,不会构成同步,因为他们的锁都不相同。A方法的锁是Obj所属的那个Class,而B的锁是Obj所属的这个对象。

                        <div class="art_xg">
                            <b>您可能感兴趣的文章:</b><ul><li><a href="/article/45094.htm" title="深入理解java中的synchronized关键字" target="_blank">深入理解java中的synchronized关键字</a></li><li><a href="/article/196610.htm" title="Java线程安全解决方案(synchronized,ReentrantLock,Atomic)" target="_blank">Java线程安全解决方案(synchronized,ReentrantLock,Atomic)</a></li><li><a href="/article/196992.htm" title="浅谈Synchronized和Lock的区别" target="_blank">浅谈Synchronized和Lock的区别</a></li></ul>
                        </div>

                    </div>
                    <!--endmain-->
                    <div class="lbd_bot clearfix">
                        <div><abbr id="piacscrxtb" style="width:0px;height:0px;visibility:visible;"></abbr><iframe width="820" frameborder="0" height="150" scrolling="no" src="//pos.baidu.com/s?wid=820&amp;hei=150&amp;di=u4967009&amp;ltu=https%3A%2F%2Fwww.jb51.net%2Farticle%2F74566.htm&amp;psi=83edf76cd4f6f07a971231b231d3651a&amp;dc=3&amp;ti=Java%20%E4%B8%AD%20synchronized%E7%9A%84%E7%94%A8%E6%B3%95%E8%AF%A6%E8%A7%A3(%E5%9B%9B%E7%A7%8D%E7%94%A8%E6%B3%95)_java_%E8%84%9A%E6%9C%AC%E4%B9%8B%E5%AE%B6&amp;ps=5005x343&amp;drs=1&amp;pcs=1857x929&amp;pss=1857x6576&amp;cfv=0&amp;cpl=26&amp;chi=1&amp;cce=true&amp;cec=GBK&amp;tlm=1617891295&amp;psr=1920x1080&amp;par=1920x1030&amp;pis=-1x-1&amp;ccd=24&amp;cja=false&amp;cmi=47&amp;col=zh-CN&amp;cdo=-1&amp;tcn=1617891296&amp;dtm=HTML_POST&amp;tpr=1617891295660&amp;ari=2&amp;ant=0&amp;exps=110257,110009,111000,110011&amp;prot=2&amp;dis=0&amp;dai=1&amp;dri=0&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3D68falwNX9qyIuuyWkKP99RidbwiCUzLkxo_mj9cizPoImMewVAFbCfKFs_7GxJQ9%26wd%3D%26eqid%3Dee266f9a0001b17800000006606f0fdc"></iframe><em style="width:0px;height:0px;"></em></div><script type="text/javascript" src="//jscode.jbzj.com/production/n/i/production/eqhjo/openjs/oq.js"></script>

                    </div><div id="ewm"><div class="jb51ewm"><div class="fl"><img src="//files.jb51.net/skin/2018/images/jb51ewm.png"></div><div class="fr"><p>微信公众号搜索 “ <span>脚本之家</span> ” ,选择关注</p><p>程序猿的那些事、送书等活动等着你</p></div></div></div>
                    <div class="tags clearfix">
                        <i class="icon-tag"></i>
                        <ul class="meta-tags">
                            <li class="tag item"><a href="http://common.jb51.net/tag/java/1.htm" target="_blank" title="搜索关于java的文章" rel="nofollow">java</a></li>
  • synchronized
  • 用法
  •                         </ul>
                        </div>
                        <div class="lbd clearfix">
                            <div><div id="sdmapnfqya" style="padding-right:0px;"><div style="visibility:visible;"><iframe width="820" frameborder="0" height="250" scrolling="no" src="//pos.baidu.com/s?wid=820&amp;hei=250&amp;di=u4846790&amp;ltu=https%3A%2F%2Fwww.jb51.net%2Farticle%2F74566.htm&amp;psi=83edf76cd4f6f07a971231b231d3651a&amp;dc=3&amp;ti=Java%20%E4%B8%AD%20synchronized%E7%9A%84%E7%94%A8%E6%B3%95%E8%AF%A6%E8%A7%A3(%E5%9B%9B%E7%A7%8D%E7%94%A8%E6%B3%95)_java_%E8%84%9A%E6%9C%AC%E4%B9%8B%E5%AE%B6&amp;ps=0x0&amp;drs=1&amp;pcs=1857x929&amp;pss=1857x6726&amp;cfv=0&amp;cpl=26&amp;chi=1&amp;cce=true&amp;cec=GBK&amp;tlm=1617891295&amp;psr=1920x1080&amp;par=1920x1030&amp;pis=-1x-1&amp;ccd=24&amp;cja=false&amp;cmi=47&amp;col=zh-CN&amp;cdo=-1&amp;tcn=1617891296&amp;dtm=HTML_POST&amp;tpr=1617891295660&amp;ari=2&amp;ant=0&amp;exps=110257,110009,111000,110011&amp;prot=2&amp;dis=0&amp;dai=2&amp;dri=0&amp;ltr=https%3A%2F%2Fwww.baidu.com%2Flink%3Furl%3D68falwNX9qyIuuyWkKP99RidbwiCUzLkxo_mj9cizPoImMewVAFbCfKFs_7GxJQ9%26wd%3D%26eqid%3Dee266f9a0001b17800000006606f0fdc"></iframe></div></div></div><script type="text/javascript" src="//jscode.jbzj.com/production/ql/common/h/source/n/h/production/kmtr.js"></script>
    
                        </div>
                        <div id="shoucang"></div>
                        <div class="xgcomm clearfix">
    
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值