スレッドを作成します。
Javaはjava.lang.Threadのクラスがスレッドを表し、すべてのスレッドオブジェクトは、Threadクラスまたはサブクラスのインスタンスでなければなりません使用しています。
Threadクラス
public class MyThread extends Thread{
public MyThread(String name) {
//调用父类的String参数的构造方法,指定线程的名称
super(name);
}
/**
* 重写run方法,完成该线程执行的逻辑
*/
@Override
public void run() {
try {
sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 0; i < 100; i++) {
System.out.println(getName() + i);
}
}
}
public class ThreadTest {
public static void main(String[] args) {
//创建自定义线程对象
MyThread mt1 = new MyThread("a");
MyThread mt2 = new MyThread("b");
MyThread mt3 = new MyThread("c");
//开启新线程
mt1.start();
mt2.start();
mt3.start();
//主线程中的for循环
for (int i = 0; i < 20; i++) {
System.out.println("主线程:"+i);
}
}
}
主なプログラムは、それらがメインで作成されたときの処理を開始する時、Java仮想マシン、メインスレッドmain()の呼び出しの実行を開始します。startメソッドは、オブジェクトMTと呼ばれていると、他の3つはまた、アプリケーション全体がマルチスレッドで実行するように、新しいスレッドを開始しました。
、Runnableインタフェース
public class MyRunnable implements Runnable{
@Override
public void run() {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
for(int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + i);
}
}
}
public class RunableTest {
public static void main(String[] args) {
MyRunnable mr = new MyRunnable();
new Thread(mr, "a").start();
new Thread(mr, "b").start();
new Thread(mr, "c").start();
}
}
、Runnableインタフェースを実装することによって、そのようなマルチスレッド型であることを特徴とします。run()メソッドは、ターゲットプログラムのマルチスレッド実行です。runメソッドの内部のすべてのマルチスレッドコード。Threadクラスは、実際には、Runnableインタフェースを実装するクラスです。
起動時のマルチスレッドでは、我々は、Threadクラスのコンストラクタスレッド(Runnableを対象)を介してオブジェクトを構築して、マルチスレッドコードを実行するために、オブジェクトの開始スレッド()メソッドを呼び出す必要があります。
スレッド実行の実質的にすべてのマルチスレッドコードを開始することによるものである()メソッドを実行します。したがって、スレッドのクラスを継承するか、最終的にスレッドクラスAPIに精通しているAPIのスレッドのスレッドオブジェクトによって制御され、マルチスレッド達成するために、Runnableインタフェースを実装するかどうかマルチスレッドプログラミングの基礎です。
Threadクラスは利点を継承するよりも、Runnableを実装します
- 同じの複数のスレッドのプログラムコードは、同じリソースを共有します
- Javaで単一継承の制限を回避するために、
- 操作デカップリング、プログラムの堅牢性を増加させる、コードは、独立して複数のスレッド、スレッドコードで共有することができます
- スレッドプールは、だけでなく、直接の継承Threadクラスには、スレッドにRunableまたは呼び出し可能なクラスを達成することができます。
Javaでは、毎回のプログラムは、少なくとも二つのスレッドを実行するために開始します。一つは、メインスレッド、ガベージコレクションスレッドです。たびに、javaコマンドを使用して、クラス、実際には、実際にはJVM、各JVMを開始しますので、それは、オペレーティングシステムのプロセスを開始することです。
スレッドセーフ
そこ場合は、同時に実行されている複数のスレッドがあり、これらのスレッドが同時にこのコードを実行することができます。各プログラムの結果、スレッドセーフである、シングルスレッド動作の結果は同じであり、また他の変数と期待の値が同じで実行します。
以下のシミュレーションでは、チケットのスレッドセーフを示しています。
public class Ticket implements Runnable {
private int ticket = 100;
@Override
public void run() {
while (true) {
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println(name + "正在卖:" + ticket);
ticket--;
}
}
}
}
public class Test1 {
public static void main(String[] args) {
Ticket ticket = new Ticket();
Thread t1 = new Thread(ticket, "窗口1");
Thread t2 = new Thread(ticket, "窗口2");
Thread t3 = new Thread(ticket, "窗口3");
t1.start();
t2.start();
t3.start();
}
}
部分的な結果:
スレッド同期
我々は、複数のスレッドが書き込み動作で同じリソース、および複数のスレッドのリソースにアクセスする使用する場合は、スレッドの安全性の問題が発生する可能性があります。
各スレッドは、通常アトミック操作を行うことができることを保証するために、Javaはスレッド同期機構を導入します。同期操作を完了するための3つの方法があります。
- シンクブロック
- 同期方法
- ロック機構
シンクブロック
synchronized
キーワードブロックのプロセスで使用することができ、このブロックは、資源が相互に排他的なアクセスであった表します。
synchronized(同步锁) {
需要同步操作的代码
}
同期ロックが抽象的概念であり、ロックオブジェクトは、新しいオブジェクトなどの任意のタイプであってもよい()とすることができます。
public class Ticket implements Runnable {
private int ticket = 100;
Object obj = new Object();
@Override
public void run() {
while (true) {
synchronized (obj) {
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println(name + "正在卖:" + ticket);
ticket--;
}
}
}
}
}
同期方法
使用同期修正された方法は、他のスレッドのブロックを待って実装プロセス内のスレッドを確保するために、同期メソッドと呼ばれます。
public synchronized void method() {
可能产生线程安全问题的代码
}
public class Ticket implements Runnable {
private int ticket = 100;
@Override
public void run() {
while (true) {
payTicket();
}
}
public synchronized void payTicket() {
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
String name = Thread.currentThread().getName();
System.out.println(name + "正在卖:" + ticket);
ticket--;
}
}
}
同期方法payTicket()は、静的に設定されてもよい、同期ロックの非静的メソッドは、(クラス名の.class)現在のバイトコードオブジェクトクラスのメソッドを使用して、この静的メソッドです。
ロックロック
また、ゲンロックとして知られているロックロック、
- ます。public voidロック():プラスゲンロック
- ます。public voidロック解除():同期ロックを解除
public class Ticket implements Runnable {
private int ticket = 100;
Lock l = new ReentrantLock();
@Override
public void run() {
while (true) {
l.lock();
if (ticket > 0) {
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}finally{
String name = Thread.currentThread().getName();
System.out.println(name + "正在卖:" + ticket);
ticket--;
l.unlock();
}
}
}
}
}