- 浏览: 188227 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (321)
- eclipse (4)
- idea (2)
- Html (8)
- Css (14)
- Javascript (8)
- Jquery (6)
- Ajax Json (4)
- Bootstrap (0)
- EasyUI (0)
- Layui (0)
- 数据结构 (0)
- Java (46)
- DesPattern (24)
- Algorithm (2)
- Jdbc (8)
- Jsp servlet (13)
- Struts2 (17)
- Hibernate (11)
- Spring (5)
- S2SH (1)
- SpringMVC (4)
- SpringBoot (11)
- WebService CXF (4)
- Poi (2)
- JFreeChart (0)
- Shiro (6)
- Lucene (5)
- ElasticSearch (0)
- JMS ActiveMQ (3)
- HttpClient (5)
- Activiti (0)
- SpringCloud (11)
- Dubbo (6)
- Docker (0)
- MySQL (27)
- Oracle (18)
- Redis (5)
- Mybatis (11)
- SSM (1)
- CentOS (10)
- Ant (2)
- Maven (4)
- Log4j (7)
- XML (5)
最新评论
1. 实现线程的两种方式
2. 线程
3. 线程变量
4. Synchronized关键字
5. Synchronized块
6. 死锁(deadlock)
7. 说明
8. 单例模式
1. 继承Thread类并重写run方法 public class ThreadTest{ public static void main(String[] args){ Thread1 t1 = new Thread1("first thread"); Thread2 t2 = new Thread2("second thread"); System.out.println(t1.getName()); System.out.println(t2.getName()); t1.start(); t2.start(); } } class Thread1 extends Thread{ public Thread1(String name){ super(name); } @Override public void run(){ for(int i = 0; i < 100; i++){ System.out.println("hello world: " + i); } } } class Thread2 extends Thread{ public Thread2(String name){ super(name); } @Override public void run(){ for(int i = 0; i < 100; i++){ System.out.println("welcome: " + i); } } } 2. 定义实现runnable接口的类进而实现run方法 public class ThreadTest2{ public static void main(String[] args){ Thread t1 = new Thread(new MyThread()); t1.start(); Thread t2 = new Thread(new MyThread2()); t2.start(); } } class MyThread implements Runnable{ @Override public void run(){ for(int i = 0; i < 100; i++){ System.out.println("hello :" + i); } } } class MyThread2 implements Runnable{ @Override public void run(){ for(int i = 0; i < 100; i++){ System.out.println("welcome: " + i); } } }
2. 线程
1) Thread类也实现了Runnable接口,因此实现了Runnable接口中的run方法; 2) 当生成一个线程对象时,如果没有为其设定名字,那么线程对象的名字将使用如下形式:Thread-number,该number将是自动增加的,并被所有的Thread对象所共享(因为它是static的成员变量)。 3) 当使用第一种方式来生成线程对象时,我们需要重写run方法,因为Thread类的run方法此时什么事情也不做。 4) 当使用第二种方式来生成线程对象时,我们需要实现Runnable接口的run方法,然后使用newThread(newMyThread())(假如MyThread已经实现了Runnable接口)来生成线程对象,这时的线程对象的run方法就会调用MyThread类的run方法,这样我们自己编写的run方法就执行了。 停止线程要重新构造方法,不能使用stop()方法。 run()方法并非是由刚创建的新线程所执行的,而是被创建新线程的当前线程所执行 start()方法才是被刚创建的新线程所执行的 run方法会等待线程执行完,再执行后面的代码 start方法会不会带线程,就会执行后面的代码 线程控制逃逸规则 某个线程控制的对象是资源本身,线程安全 某个线程控制的对象仅仅是某个资源的引用,线程不安全
3. 线程变量
HelloThread中i定义的位置。 线程的全局变量只有一个,而局部变量每一个都会有一个。 关于成员变量与局部变量:如果一个变量是成员变量,那么多个线程对同一个对象的成员变量进行操作时,他们对该成员变量是彼此影响的(也就是说一个线程对成员变量的改变会影响到另一个线程)。 public class ThreadTest3{ public static void main(String[] args){ Runnable r = new HelloThread(); Thread t1 = new Thread(r); //r = new HelloThread(); Thread t2 = new Thread(r); t1.start(); t2.start(); } } class HelloThread implements Runnable{ int i; @Override public void run(){ int i = 0; while(true){ System.out.println("number: " + this.i++); try{ Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e){ e.printStackTrace(); } if(50 == this.i){ break; } } } }
4. Synchronized关键字
当synchronized关键字修饰一个方法的时候,该方法叫做同步方法。 public class FetchMoney{ public static void main(String[] args){ Bank bank = new Bank(); Thread t1 = new MoneyThread(bank); // 柜台 //bank = new Bank(); Thread t2 = new MoneyThread(bank); // 取款机 t1.start(); t2.start(); } } class Bank{ private int money = 1000; public synchronized int getMoney(int number){ if(number < 0){ return -1; } else if(number > money){ return -2; } else if(money < 0){ return -3; } else{ try{ Thread.sleep(1000); } catch (InterruptedException e){ e.printStackTrace(); } money -= number; System.out.println("left money: " + money); return number; } } } class MoneyThread extends Thread{ private Bank bank; public MoneyThread(Bank bank){ this.bank = bank; } @Override public void run(){ System.out.println(bank.getMoney(800)); } } Java中的每个对象都有一个锁(lock)或者叫做监视器(monitor),当访问某个对象的synchronized方法时,表示将该对象上锁,此时其他任何线程都无法再去访问该synchronized方法了,直到之前的那个线程执行方法完毕后(或者是抛出了异常),那么将该对象的锁释放掉,其他线程才有可能再去访问该synchronized方法。 如果一个对象有多个synchronized方法,某一时刻某个线程已经进入到了某个synchronized方法,那么在该方法没有执行完毕前,其他线程是无法访问该对象的任何synchronized方法的。 public class ThreadTest4{ public static void main(String[] args){ Example example = new Example(); Thread t1 = new TheThread(example); // 区分一个对象还是两个对象 // example = new Example(); Thread t2 = new TheThread2(example); t1.start(); t2.start(); } } class Example{ //static对顺序的影响 public synchronized void execute(){ for(int i = 0; i < 20; i++){ try{ Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e){ e.printStackTrace(); } System.out.println("hello: " + i); } } //static对顺序的影响 public synchronized void execute2(){ for(int i = 0; i < 20; i++){ try{ Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e){ e.printStackTrace(); } System.out.println("world: " + i); } } } class TheThread extends Thread{ private Example example; public TheThread(Example example){ this.example = example; } @Override public void run(){ this.example.execute(); } } class TheThread2 extends Thread{ private Example example; public TheThread2(Example example){ this.example = example; } @Override public void run(){ this.example.execute2(); } } 1) Static方法是属于类的,不是属于对象的。它对应的对象是class对象。 一个类有两个synchronized static方法,则先执行一个,后执行另一个。 2) 如果某个synchronized方法是static的,那么当线程访问该方法时,它锁的并不是synchronized方法所在的对象,而是synchronized方法所在的对象所对应的Class对象,因为Java中无论一个类有多少个对象,这些对象会对应唯一一个Class对象,因此当线程分别访问同一个类的两个对象的两个static,synchronized方法时,他们的执行顺序也是顺序的,也就是说一个线程先去执行方法,执行完毕后另一个线程才开始执行。
5. Synchronized块
Synchronized块(比synchronized方法更加细粒度)对object进行上锁(传入的object是否是一个object)。 public class ThreadTest5{ public static void main(String[] args){ Example2 e = new Example2(); TheThread3 t1 = new TheThread3(e); e = new Example2(); TheThread4 t2 = new TheThread4(e); t1.start(); t2.start(); } } class Example2{ private Object object = new Object(); public void execute(){ synchronized (this){ for (int i = 0; i < 20; i++){ try{ Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e){ e.printStackTrace(); } System.out.println("hello: " + i); } } } public void execute2(){ synchronized(this){ for (int i = 0; i < 20; i++){ try{ Thread.sleep((long) (Math.random() * 1000)); } catch (InterruptedException e){ e.printStackTrace(); } System.out.println("world: " + i); } } } } class TheThread3 extends Thread{ private Example2 example; public TheThread3(Example2 example){ this.example = example; } @Override public void run(){ this.example.execute(); } } class TheThread4 extends Thread{ private Example2 example; public TheThread4(Example2 example){ this.example = example; } @Override public void run(){ this.example.execute2(); } } 两个对象一定的乱序的。
6. 死锁(deadlock)
wait方法,调用必须在synchronized方法或块当中。 public class Sample{ private int number; public synchronized void increase(){ while (0 != number){ try{ wait(); } catch (InterruptedException e){ e.printStackTrace(); } } number++; System.out.println(number); notify(); } public synchronized void decrease(){ while (0 == number){ try{ wait(); } catch (InterruptedException e){ e.printStackTrace(); } } number--; System.out.println(number); notify(); } } public class IncreaseThread extends Thread{ private Sample sample; public IncreaseThread(Sample sample){ this.sample = sample; } @Override public void run(){ for(int i = 0; i < 20; i++){ try{ Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e){ e.printStackTrace(); } sample.increase(); } } } public class DecreaseThread extends Thread{ private Sample sample; public DecreaseThread(Sample sample){ this.sample = sample; } @Override public void run(){ for(int i = 0; i < 20; i++){ try{ Thread.sleep((long)(Math.random() * 1000)); } catch (InterruptedException e){ e.printStackTrace(); } sample.decrease(); } } } public class MainTest{ public static void main(String[] args){ Sample sample = new Sample(); Thread t1 = new IncreaseThread(sample); Thread t2 = new DecreaseThread(sample); Thread t3 = new IncreaseThread(sample); Thread t4 = new DecreaseThread(sample); t1.start(); t2.start(); t3.start(); t4.start(); } } 4个线程的时候wait之后还需要判断用while不用if。
7. 说明
wait与notify方法都是定义在Object类中,而且是final的,因此会被所有的Java类所继承并且无法重写。这两个方法要求在调用时线程应该已经获得了对象的锁,因此对这两个方法的调用需要放在synchronized方法或块当中。当线程执行了wait方法时,它会释放掉对象的锁。 另一个会导致线程暂停的方法就是Thread类的sleep方法,它会导致线程睡眠指定的毫秒数,但线程在睡眠的过程中是不会释放掉对象的锁的。
8. 单例模式
对于单例模式(Singleton)来说,如果在getInstance()方法中生成Singleton实例则可能会产生同步问题,即可能会生成两个不同的对象。 public class Singleton{ private static Singleton singleton; private Singleton(){} public static Singleton getInstance(){ if (null == singleton){ try{ Thread.sleep((long) (Math.random() * 4000)); } catch (InterruptedException e){ e.printStackTrace(); } singleton = new Singleton(); } return singleton; } public static void main(String[] args){ new MyThread().start(); new MyThread().start(); } } class MyThread extends Thread{ @Override public void run(){ System.out.println(Singleton.getInstance()); } } 运行结果: code17.Singleton@1fa1bb6 code17.Singleton@1315d34
发表评论
-
Java中获取IP地址、子网掩码、网关地址
2019-06-26 10:53 01. Java中获取IP地址、子网掩码、网关地址、ping连通 ... -
Java中ThreadLocal
2019-04-19 10:44 01. Java中ThreadLocal Java中的Th ... -
Java中原子性锁synchronized、Lock
2019-04-18 15:19 01. synchronized依赖JVM 1) 修饰代码 ... -
Java中原子性Atomic
2019-04-18 14:45 01. Atomic包简介 java.util.concu ... -
开发常用链接
2019-03-26 11:21 0在线工具:http://tool.oschina.net/ ... -
java1234学习目录
2019-03-21 11:08 01-01-01 N01 J2SEv2(41课时) ... -
Java中TCP和UDP
2018-10-25 10:55 3401. 网页内容获取 Url1.java impor ... -
Java中serializable序列化
2018-10-24 14:46 4701. 序列化 transient不会被序列化。 imp ... -
Java中CharSet集
2018-10-24 11:31 5371. CharSet集 import java.nio. ... -
Java中RandomAccessFile类
2018-10-24 11:30 4981. RandomAccessFile类 1. 使用Ra ... -
Java中I/O的字符流InputStreamReader和OutputStreamWriter
2018-10-22 09:43 4371. InputStreamReader和OutputStre ... -
Java中其它输入输出流
2018-10-22 09:08 4661. ByteArrayInputStream流 以ar ... -
Java中I/O的OutputStream流
2018-10-22 08:54 4831. Java中I/O的OutputStream流 1. ... -
Java中I/O的InputStream流
2018-10-22 08:42 4611. Java中I/O的InputStream流 1. ... -
Java中I/O的File类
2018-10-19 13:45 4301. Java中I/O的File类 1. 在window ... -
Java中innerClass内部类
2018-10-18 09:37 4341. Java中innerClass内部类 用AA.BB ... -
Java中adapter适配器
2018-10-18 08:36 5801. Java中adapter适配器 适配器adapte ... -
Java中awt包
2018-10-17 11:26 17051. Java中awt包 AWT事件模型Event 1 ... -
Java中frame对象
2018-10-17 10:56 6671. Java中frame对象 1. Frame对象 ... -
Java中exception异常
2018-10-17 10:24 4091. Java中exception异常 Java中的异常 ...
相关推荐
在Java中,线程并发可以通过多种方式实现,包括继承Thread类、实现Runnable接口以及使用ExecutorService和Future等高级API。下面将详细探讨这些知识点。 首先,Java中创建线程主要有两种方法。一种是通过继承Thread...
在Java中,通常我们通过Java的`java.lang.Thread`类进行线程的创建和管理,但默认情况下,Java并不提供直接设置线程亲和性的API。Java-Thread-Affinity库填补了这一空白,它允许开发者在Java程序中方便地绑定线程到...
Java多线程机制是Java编程中至关重要的一部分,它允许程序同时执行多个任务,提升应用程序的效率和响应性。以下是对各个知识点的详细说明: 9.1 Java中的线程: Java程序中的线程是在操作系统级别的线程基础上进行...
在Java编程语言中,创建线程是实现并发执行任务的关键步骤。Java提供了两种主要的方法来创建线程,分别是直接继承自`Thread`类和实现`Runnable`接口。这两种方法各有其特点和适用场景。 1. **继承Thread类**: 当...
为了在多线程中同步进度更新,我们可以利用synchronized关键字、wait()、notify()方法,或者使用Java并发库中的高级工具,如Semaphore、CyclicBarrier或CountDownLatch等。 一个简单的进度条实现可以采用共享变量...
在Java中,实现多线程有两种主要方式:继承Thread类和实现Runnable接口。 1. 继承Thread类: 当我们创建一个新的类,让它继承Thread类时,可以通过重写`run()`方法来定义线程执行的任务。然后创建该类的对象,并...
java线程第二版中英文 java线程第二版中英文 线程并不是新的概念:许多操作系统和语言都支持它们。在Java出现以前,似乎人人都在谈论线程,却很少有人使用它。用线程编程是技巧性很强的且不可移植。 而在Java中却...
Java Thread多线程全面解析涵盖了Java编程中关于线程的重要概念和实践技巧。在Java中,多线程是并发编程的基础,允许程序同时执行多个任务,提高系统资源利用率和应用程序的响应速度。 线程的生命周期包括五个基本...
1. Thread 类:Thread 类是 Java 中的基本线程类,提供了创建和管理线程的方法。 2. Runnable 接口:Runnable 接口是 Java 中的基本线程接口,提供了线程的执行方法。 线程同步 Java 中的多线程编程需要解决线程...
在Java中,创建线程有两种主要方式:继承`Thread`类或实现`Runnable`接口。这里,我们假设`Thread.java`中定义了一个名为`MyThread`的类,它直接继承自`Thread`: ```java public class MyThread extends Thread { ...
2. **JAVA多线程API**:论文会详细阐述JAVA提供的多线程API,如Thread类、Runnable接口、ExecutorService和Future接口等。通过实例解析这些类和接口的使用方法,帮助读者理解如何在实际编程中创建和管理线程。 3. *...
Java多线程是Java编程语言中一个非常重要的概念,它允许开发者在一个程序中创建多个执行线程并行运行,以提高程序的执行效率和响应速度。在Java中,线程的生命周期包含五个基本状态,分别是新建状态(New)、就绪...
SwingWorker 提供了在后台线程中执行任务并在事件调度线程中更新UI的能力,确保了界面的响应性。 以下是一个简单的示例,展示了如何创建一个基于控制台的进度条(对于GUI的实现,可以参考SwingWorker或Task的相关...
此外,Java中的线程优先级(`Thread.setPriority()`)可以影响线程调度,但同样不应过度依赖。优先级高的线程在调度时理论上会得到更多执行机会,但Java的线程调度策略可能会使这种优先级关系变得复杂,尤其是在多...
首先,`Thread`类是Java中的核心类,它代表了程序中的一个执行线程。当你创建一个新的`Thread`对象并启动它时,Java虚拟机(JVM)会为这个线程分配CPU时间片,从而使得代码可以在不同的线程间交替执行。 要实现...
在Java编程语言中,线程是程序执行的基本单元,它允许程序并发地执行多个任务。在多线程环境中,程序的执行效率和响应性通常会得到显著提升。本篇文章将详细探讨如何在Java中启动线程,以及相关的重要概念和技术。 ...
在Java中,创建线程主要有两种方式:继承Thread类和实现Runnable接口。在提供的实例中,我们可能会看到这两种方式的运用。 1. 继承Thread类:通过创建新的Thread子类并重写其run()方法,然后创建该子类的实例并调用...
在Java中,线程休眠主要通过`Thread.sleep()`方法实现。 1. **Thread.sleep()方法详解** `Thread.sleep(long millis)`方法用于使当前正在执行的线程暂停执行,参数`millis`代表线程将睡眠的毫秒数。如果参数是0,...
继承Thread类: 1必须重写run 方法:里面放置的实际的线程体 2 启动线程: 3创建Thread对象 4调用Thread对象的start 方法启动线程