多线程介绍和创建
一 什么是线程
我的答案就是 启动一个jvm 就是启动了一个进程 然后操作系统就给进程分配内存空间, 然后jvm启动main方法,就是启动了一个main线程 然后就是在栈空间分配main线程的栈帧 就是进程的一条执行路径
简单理解就是liunx系统启动程序是以进程级别运行的, 进程是以线程为基本单位运行的, 粒度更细!
在jvm启动的时候 至少启动了一个main线程和一个gc线程 当然还有其他的一些线程
二 线程和进程的区别
- 调度
进程是操作系统分配资源的一个基本单位。线程是 CPU调度的基本单位。
并发性
一个进程里面可以有多个线程执行
独立性
在同一进程中线程的独立性要比在不同的进程中独立性要低很多
系统开销
线程切换的开销低于进程切换的开销
三 java thread api
A <i>thread</i> is a thread of execution in a program. The Java
* Virtual Machine allows an application to have multiple threads of
* execution running concurrently.
When a Java Virtual Machine starts up, there is usually a single
* non-daemon thread (which typically calls the method named
* <code>main</code> of some designated class). The Java Virtual
* Machine continues to execute threads until either of the following
* occurs:
创建线程的2种方法:
There are two ways to create a new thread of execution. One is to
* declare a class to be a subclass of <code>Thread</code>. This
* subclass should override the <code>run</code> method of class
* <code>Thread</code>. An instance of the subclass can then be
* allocated and started。
/**
* Causes this thread to begin execution; the Java Virtual Machine
* calls the <code>run</code> method of this thread.
* <p>
* The result is that two threads are running concurrently: the
* current thread (which returns from the call to the
* <code>start</code> method) and the other thread (which executes its
* <code>run</code> method).
* <p>
* It is never legal to start a thread more than once.
* In particular, a thread may not be restarted once it has completed
* execution.
*/
public synchronized void start()
public void run()
// thread 的构造函数
public Thread()
public Thread(Runnable target)
public Thread(Runnable target, AccessControlContext acc)
public Thread(ThreadGroup group, Runnable target)
public Thread(String name)
public Thread(ThreadGroup group, String name)
public Thread(Runnable target, String name)
public Thread(ThreadGroup group, Runnable target, String name)
// stackSize 线程栈内存的大小 这个是比较重要的参数
public Thread(ThreadGroup group, Runnable target, String name,long stackSize)
四 java创建线程
继承Thread
<!–hexoPostRenderEscape:
public class TryConcurrency {
public static void main(String[] args){<span class="token keyword">new</span> <span class="token class-name">Thread</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">-></span> <span class="token punctuation">{</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"我是"</span> <span class="token operator">+</span> <span class="token class-name">Thread</span><span class="token punctuation">.</span><span class="token function">currentThread</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token class-name">Thread</span><span class="token punctuation">.</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">InterruptedException</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span> e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
}
}
我是Thread[Thread-0,5,main]
:hexoPostRenderEscape–>
我是Thread[Thread-0,5,main]
我是Thread[Thread-0,5,main]
实现Runable
Runnable r = () -> { while (true){ System.out.println("我是实现了Runnable: " + Thread.currentThread()); try { Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } }; new Thread(r).start();
使用Callable
Callable<Integer> c = () -> { int sum = 0; for (int i = 0; i <= 100000; i++) { sum += i; } return sum; }; FutureTask<Integer> result = new FutureTask(c); new Thread(result).start(); try { Integer o = result.get(); System.out.println(o); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } 705082704
使用线程池
//构造一个线程池 ThreadPoolExecutor threadPool = new ThreadPoolExecutor( 1, 1, 10, TimeUnit.SECONDS, new ArrayBlockingQueue<>(1), new ThreadPoolExecutor.DiscardOldestPolicy()); threadPool.execute(() -> { try { while (true){ System.out.println("----"+Thread.currentThread()); Thread.sleep(1000); } } catch (Exception e) { e.printStackTrace(); }finally{ threadPool.shutdown();// 关闭线程池 } });
四 线程的生命周期
- 线程状态
- new — new Thread()
- runnable — start()
- running
- block
- termate
- 线程的start方法不能调用2次
- start方法使用了模板设计模式 start - start0是本地方法 run方法其实就是一个模板方法 需要实现的方法
五 模拟银行排队叫号
public class TickWindow extends Thread{
private final String name;
public TickWindow(String name) {
this.name = name;
}
private static int MAX = 50;
// 加static 有问题 和 不加static 有线程安全问题
private static int index = 1;
@Override
public void run() {
while (index <= MAX){
System.out.println("当前柜台是: "+name+" 当前号码是: index " + index++);
}
}
}
public class Bank {
public static void main(String[] args) {
new TickWindow("一号柜台").start();
new TickWindow("二号柜台").start();
new TickWindow("三号柜台").start();
}
}
六 用runabble接口分离线程和业务逻辑
:hexoPostRenderEscape–>public class TestRunnable implements Runnable { public static void main(String[] args) { TestRunnable testRunnable = new TestRunnable(); new Thread(testRunnable).start(); new Thread(testRunnable).start(); new Thread(testRunnable).start(); } private static final int MAX = 50; //这里有一个线程安全的问题 private int index = 0; @Override public void run() { while (index <= MAX){ System.out.println(Thread.currentThread().getName() + " hello ----> " + index++);
<span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token class-name">Thread</span><span class="token punctuation">.</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">InterruptedException</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span> e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span>
}
这种方式其实是使用了策略模式
七 Thread的api
:hexoPostRenderEscape–>1. 守护线程api t.setDaemon() * Marks this thread as either a {@linkplain #isDaemon daemon} thread * or a user thread. The Java Virtual Machine exits when the only * threads running are all daemon threads. * * <p> This method must be invoked before the thread is started. // 设置线程为守护线程 public final void setDaemon(boolean on) public static void main(String[] args) { Thread t = new Thread(()->{ try { System.out.println(Thread.currentThread().getName() + "running"); Thread.sleep(10000); System.out.println(Thread.currentThread().getName() + "Done"); } catch (InterruptedException e) { e.printStackTrace(); } }); // 守护线程意思是 主线程死亡 守护线程不管是什么状态 也死亡 t.setDaemon(true); // 必须要在start()前面 t.start(); System.out.println(Thread.currentThread().getName()); } 2. 线程id t1.getId() 3. 线程名称 t1.getName() 4. 线程优先级 t1.setPriority(Thread.MAX_PRIORITY); 用处并不是很大 5. 线程状态 State getState() 6. 线程的join()方法 * Waits for this thread to die. * * <p> An invocation of this method behaves in exactly the same * way as the invocation public final void join() public final synchronized void join(long millis, int nanos) public final synchronized void join(long millis) public static void main(String[] args) throws InterruptedException { Thread t1 = new Thread(()->{ IntStream.range(1, 1000).forEach(i->{ System.out.println(Thread.currentThread().getName() + " --> " + i);
<span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> t1<span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token comment">//放到start之后</span> <span class="token comment">//先把t1 先执行完 再执行主线程 main线程等t1结束</span> t1<span class="token punctuation">.</span><span class="token function">join</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">IntStream</span><span class="token punctuation">.</span><span class="token function">range</span><span class="token punctuation">(</span><span class="token number">1</span><span class="token punctuation">,</span> <span class="token number">1000</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">forEach</span><span class="token punctuation">(</span>i<span class="token operator">-></span><span class="token punctuation">{</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token class-name">Thread</span><span class="token punctuation">.</span><span class="token function">currentThread</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">getName</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token operator">+</span> <span class="token string">" --> "</span> <span class="token operator">+</span> i<span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
7. 中断线程 interrupt()
Interrupts this thread.
<p> Unless the current thread is interrupting itself, which is
always permitted, the {@link #checkAccess() checkAccess} method
of this thread is invoked, which may cause a {@link
SecurityException} to be thrown.<span class="token keyword">public</span> <span class="token keyword">void</span> <span class="token function">interrupt</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">boolean</span> <span class="token function">interrupted</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">public</span> <span class="token keyword">boolean</span> <span class="token function">isInterrupted</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">private</span> <span class="token keyword">native</span> <span class="token keyword">boolean</span> <span class="token function">isInterrupted</span><span class="token punctuation">(</span><span class="token keyword">boolean</span> <span class="token class-name">ClearInterrupted</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">public</span> <span class="token keyword">static</span> <span class="token keyword">void</span> <span class="token function">main</span><span class="token punctuation">(</span><span class="token class-name">String</span><span class="token punctuation">[</span><span class="token punctuation">]</span> args<span class="token punctuation">)</span> <span class="token keyword">throws</span> <span class="token class-name">InterruptedException</span> <span class="token punctuation">{</span> <span class="token class-name">Thread</span> t1 <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Thread</span><span class="token punctuation">(</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">-></span><span class="token punctuation">{</span> <span class="token keyword">while</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span><span class="token punctuation">{</span> <span class="token keyword">try</span> <span class="token punctuation">{</span> <span class="token class-name">Thread</span><span class="token punctuation">.</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">10</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">InterruptedException</span> e<span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span><span class="token string">"interrupte"</span><span class="token punctuation">)</span><span class="token punctuation">;</span> e<span class="token punctuation">.</span><span class="token function">printStackTrace</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token keyword">break</span><span class="token punctuation">;</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span><span class="token punctuation">)</span><span class="token punctuation">;</span> t1<span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">Thread</span><span class="token punctuation">.</span><span class="token function">sleep</span><span class="token punctuation">(</span><span class="token number">100</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>t1<span class="token punctuation">.</span><span class="token function">isInterrupted</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> t1<span class="token punctuation">.</span><span class="token function">interrupt</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token class-name">System</span><span class="token punctuation">.</span>out<span class="token punctuation">.</span><span class="token function">println</span><span class="token punctuation">(</span>t1<span class="token punctuation">.</span><span class="token function">isInterrupted</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span> <span class="token punctuation">}</span>
8. 优雅的结束线程